Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Support for underscores in namespaces

  • Loading branch information...
commit d123f064854361d6b589a682618e0425ed2571c1 1 parent 5fe88b1
Brian Ploetz authored
View
7 activesupport/lib/active_support/core_ext/string/inflections.rb
@@ -50,6 +50,7 @@ def singularize
# "Module".constantize # => Module
# "Class".constantize # => Class
# "blargle".constantize # => NameError: wrong constant name blargle
+ # "V0_1_0".constantize # => V0_1_0
def constantize
ActiveSupport::Inflector.constantize(self)
end
@@ -62,6 +63,7 @@ def constantize
# "Module".safe_constantize # => Module
# "Class".safe_constantize # => Class
# "blargle".safe_constantize # => nil
+ # "V0_1_0".safe_constantize # => V0_1_0
def safe_constantize
ActiveSupport::Inflector.safe_constantize(self)
end
@@ -69,12 +71,15 @@ def safe_constantize
# By default, +camelize+ converts strings to UpperCamelCase. If the argument to camelize
# is set to <tt>:lower</tt> then camelize produces lowerCamelCase.
#
- # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
+ # +camelize+ will convert '/' to '::' which is useful for converting paths to namespaces.
+ # +camelize+ will convert '__' to '_' which is useful for namespaces containing underscores.
#
# "active_record".camelize # => "ActiveRecord"
# "active_record".camelize(:lower) # => "activeRecord"
# "active_record/errors".camelize # => "ActiveRecord::Errors"
# "active_record/errors".camelize(:lower) # => "activeRecord::Errors"
+ # "api/v0__1__0".camelize # => "API::V0_1_0"
+ # "api/v0__1__0".camelize(:lower) # => "API::V0_1_0"
def camelize(first_letter = :upper)
case first_letter
when :upper then ActiveSupport::Inflector.camelize(self, true)
View
11 activesupport/lib/active_support/inflector/methods.rb
@@ -39,13 +39,16 @@ def singularize(word)
# By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+
# is set to <tt>:lower</tt> then +camelize+ produces lowerCamelCase.
#
- # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
+ # +camelize+ will convert '/' to '::' which is useful for converting paths to namespaces.
+ # +camelize+ will convert '__' to '_' which is useful for namespaces containing underscores.
#
# Examples:
# "active_model".camelize # => "ActiveModel"
# "active_model".camelize(:lower) # => "activeModel"
# "active_model/errors".camelize # => "ActiveModel::Errors"
# "active_model/errors".camelize(:lower) # => "activeModel::Errors"
+ # "api/v0__1__0".camelize # => "API::V0_1_0"
+ # "api/v0__1__0".camelize(:lower) # => "API::V0_1_0"
#
# As a rule of thumb you can think of +camelize+ as the inverse of +underscore+,
# though there are cases where that does not hold:
@@ -58,16 +61,19 @@ def camelize(term, uppercase_first_letter = true)
else
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('/', '::')
+ string = string.gsub('__', '*')
+ string = string.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }.gsub('/', '::').gsub('*', '_')
end
# Makes an underscored, lowercase form from the expression in the string.
#
# Changes '::' to '/' to convert namespaces to paths.
+ # Changes '_' to '__' to allow underscores in namespaces.
#
# Examples:
# "ActiveModel".underscore # => "active_model"
# "ActiveModel::Errors".underscore # => "active_model/errors"
+ # "Api::V0_1_0".underscore # => "api/v0__1__0"
#
# As a rule of thumb you can think of +underscore+ as the inverse of +camelize+,
# though there are cases where that does not hold:
@@ -76,6 +82,7 @@ def camelize(term, uppercase_first_letter = true)
def underscore(camel_cased_word)
word = camel_cased_word.to_s.dup
word.gsub!(/::/, '/')
+ word.gsub!(/([A-Z\d])(_)/,'\1__') if !word.include?('__')
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')
View
4 activesupport/test/inflector_test.rb
@@ -180,6 +180,10 @@ def test_underscore
end
end
+ def test_underscores_in_namespace_idempotent_when_underscored
+ assert_equal("v0__1__0/application", ActiveSupport::Inflector.underscore("v0__1__0/application"))
+ end
+
def test_camelize_with_module
CamelWithModuleToUnderscoreWithSlash.each do |camel, underscore|
assert_equal(camel, ActiveSupport::Inflector.camelize(underscore))
View
23 activesupport/test/inflector_test_cases.rb
@@ -115,21 +115,27 @@ module InflectorTestCases
"Product" => "product",
"SpecialGuest" => "special_guest",
"ApplicationController" => "application_controller",
- "Area51Controller" => "area51_controller"
+ "Area51Controller" => "area51_controller",
+ "V0_1_0" => "v0__1__0",
+ "APIVersion0_1_0" => "api_version0__1__0"
}
UnderscoreToLowerCamel = {
"product" => "product",
"special_guest" => "specialGuest",
"application_controller" => "applicationController",
- "area51_controller" => "area51Controller"
+ "area51_controller" => "area51Controller",
+ "v0__1__0" => "v0_1_0",
+ "api_version0__1__0" => "apiVersion0_1_0"
}
SymbolToLowerCamel = {
:product => 'product',
:special_guest => 'specialGuest',
:application_controller => 'applicationController',
- :area51_controller => 'area51Controller'
+ :area51_controller => 'area51Controller',
+ :v0__1__0 => "v0_1_0",
+ :api_version0__1__0 => "apiVersion0_1_0"
}
CamelToUnderscoreWithoutReverse = {
@@ -137,22 +143,29 @@ module InflectorTestCases
"HTMLTidyGenerator" => "html_tidy_generator",
"FreeBSD" => "free_bsd",
"HTML" => "html",
+ "V0_1_0" => "v0__1__0"
}
CamelWithModuleToUnderscoreWithSlash = {
"Admin::Product" => "admin/product",
"Users::Commission::Department" => "users/commission/department",
"UsersSection::CommissionDepartment" => "users_section/commission_department",
+ "API::V0_1_0::Component" => "api/v0__1__0/component",
+ "APIVersion::V0_1_0::Component" => "api_version/v0__1__0/component",
+ "APIVersionV0_1_0::Component" => "api_version_v0__1__0/component",
+ "APIVersion0_1_0::Component" => "api_version0__1__0/component"
}
ClassNameToForeignKeyWithUnderscore = {
"Person" => "person_id",
- "MyApplication::Billing::Account" => "account_id"
+ "MyApplication::Billing::Account" => "account_id",
+ "API::V0_1_0::Component" => "component_id"
}
ClassNameToForeignKeyWithoutUnderscore = {
"Person" => "personid",
- "MyApplication::Billing::Account" => "accountid"
+ "MyApplication::Billing::Account" => "accountid",
+ "API::V0_1_0::Component" => "componentid"
}
ClassNameToTableName = {
Please sign in to comment.
Something went wrong with that request. Please try again.