aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG2
-rw-r--r--activesupport/lib/active_support/configurable.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/array/wrap.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/module/attribute_accessors.rb8
-rw-r--r--activesupport/lib/active_support/core_ext/string/inflections.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/string/output_safety.rb2
-rw-r--r--activesupport/lib/active_support/inflector/inflections.rb145
-rw-r--r--activesupport/lib/active_support/inflector/methods.rb105
-rw-r--r--activesupport/lib/active_support/ordered_options.rb4
-rw-r--r--activesupport/lib/active_support/version.rb4
-rw-r--r--activesupport/test/configurable_test.rb22
-rw-r--r--activesupport/test/core_ext/array_ext_test.rb5
-rw-r--r--activesupport/test/core_ext/module/attribute_accessor_test.rb7
-rw-r--r--activesupport/test/core_ext/string_ext_test.rb4
-rw-r--r--activesupport/test/inflector_test.rb86
-rw-r--r--activesupport/test/inflector_test_cases.rb3
-rw-r--r--activesupport/test/time_zone_test.rb8
17 files changed, 292 insertions, 120 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index 23f25d6197..034d03533f 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,5 +1,7 @@
*Rails 3.2.0 (unreleased)*
+* The inflector understands acronyms. [dlee]
+
* Deprecated ActiveSupport::Memoizable in favor of Ruby memoization pattern [José Valim]
* Added Time#all_day/week/quarter/year as a way of generating ranges (example: Event.where(created_at: Time.now.all_week)) [DHH]
diff --git a/activesupport/lib/active_support/configurable.rb b/activesupport/lib/active_support/configurable.rb
index a94446acde..a2d2719de7 100644
--- a/activesupport/lib/active_support/configurable.rb
+++ b/activesupport/lib/active_support/configurable.rb
@@ -12,12 +12,12 @@ module ActiveSupport
class Configuration < ActiveSupport::InheritableOptions
def compile_methods!
- self.class.compile_methods!(keys.reject {|key| respond_to?(key)})
+ self.class.compile_methods!(keys)
end
# compiles reader methods so we don't have to go through method_missing
def self.compile_methods!(keys)
- keys.each do |key|
+ keys.reject { |m| method_defined?(m) }.each do |key|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{key}; _get(#{key.inspect}); end
RUBY
diff --git a/activesupport/lib/active_support/core_ext/array/wrap.rb b/activesupport/lib/active_support/core_ext/array/wrap.rb
index f420270dc4..4834eca8b1 100644
--- a/activesupport/lib/active_support/core_ext/array/wrap.rb
+++ b/activesupport/lib/active_support/core_ext/array/wrap.rb
@@ -40,7 +40,7 @@ class Array
if object.nil?
[]
elsif object.respond_to?(:to_ary)
- object.to_ary
+ object.to_ary || [object]
else
[object]
end
diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
index 871f5cef3b..be94ae1565 100644
--- a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
@@ -12,7 +12,7 @@ class Module
end
EOS
- unless options[:instance_reader] == false
+ unless options[:instance_reader] == false || options[:instance_accessor] == false
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
def #{sym}
@@#{sym}
@@ -31,7 +31,7 @@ class Module
end
EOS
- unless options[:instance_writer] == false
+ unless options[:instance_writer] == false || options[:instance_accessor] == false
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
def #{sym}=(obj)
@@#{sym} = obj
@@ -53,6 +53,10 @@ class Module
# end
#
# AppConfiguration.google_api_key = "overriding the api key!"
+ #
+ # To opt out of the instance writer method, pass :instance_writer => false.
+ # To opt out of the instance reader method, pass :instance_reader => false.
+ # To opt out of both instance methods, pass :instance_accessor => false.
def mattr_accessor(*syms)
mattr_reader(*syms)
mattr_writer(*syms)
diff --git a/activesupport/lib/active_support/core_ext/string/inflections.rb b/activesupport/lib/active_support/core_ext/string/inflections.rb
index 2f0676f567..002688d6c0 100644
--- a/activesupport/lib/active_support/core_ext/string/inflections.rb
+++ b/activesupport/lib/active_support/core_ext/string/inflections.rb
@@ -1,5 +1,4 @@
require 'active_support/inflector/methods'
-require 'active_support/inflector/inflections'
require 'active_support/inflector/transliterate'
# String inflections define new methods on the String class to transform names for different purposes.
diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb
index 07cb2187e3..3bf4edbdef 100644
--- a/activesupport/lib/active_support/core_ext/string/output_safety.rb
+++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -67,7 +67,7 @@ class Object
end
end
-class Fixnum
+class Numeric
def html_safe?
true
end
diff --git a/activesupport/lib/active_support/inflector/inflections.rb b/activesupport/lib/active_support/inflector/inflections.rb
index d5d55b7207..90bb62f57b 100644
--- a/activesupport/lib/active_support/inflector/inflections.rb
+++ b/activesupport/lib/active_support/inflector/inflections.rb
@@ -20,10 +20,61 @@ 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 = [], [], [], []
+ @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
+ # string that contains the acronym will retain the acronym when passed to `camelize`, `humanize`, or `titleize`.
+ # A camelized string that contains the acronym will maintain the acronym when titleized or humanized, and will
+ # convert the acronym into a non-delimited single lowercase word when passed to +underscore+.
+ #
+ # Examples:
+ # acronym 'HTML'
+ # titleize 'html' #=> 'HTML'
+ # camelize 'html' #=> 'HTML'
+ # underscore 'MyHTML' #=> 'my_html'
+ #
+ # The acronym, however, must occur as a delimited unit and not be part of another word for conversions to recognize it:
+ #
+ # acronym 'HTTP'
+ # camelize 'my_http_delimited' #=> 'MyHTTPDelimited'
+ # camelize 'https' #=> 'Https', not 'HTTPs'
+ # underscore 'HTTPS' #=> 'http_s', not 'https'
+ #
+ # acronym 'HTTPS'
+ # camelize 'https' #=> 'HTTPS'
+ # underscore 'HTTPS' #=> 'https'
+ #
+ # Note: Acronyms that are passed to `pluralize` will no longer be recognized, since the acronym will not occur as
+ # a delimited unit in the pluralized result. To work around this, you must specify the pluralized form as an
+ # acronym as well:
+ #
+ # acronym 'API'
+ # camelize(pluralize('api')) #=> 'Apis'
+ #
+ # acronym 'APIs'
+ # camelize(pluralize('api')) #=> 'APIs'
+ #
+ # `acronym` may be used to specify any word that contains an acronym or otherwise needs to maintain a non-standard
+ # capitalization. The only restriction is that the word must begin with a capital letter.
+ #
+ # Examples:
+ # acronym 'RESTful'
+ # underscore 'RESTful' #=> 'restful'
+ # underscore 'RESTfulController' #=> 'restful_controller'
+ # titleize 'RESTfulController' #=> 'RESTful Controller'
+ # camelize 'restful' #=> 'RESTful'
+ # camelize 'restful_controller' #=> 'RESTfulController'
+ #
+ # acronym 'McDonald'
+ # underscore 'McDonald' #=> 'mcdonald'
+ # camelize 'mcdonald' #=> 'McDonald'
+ def acronym(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.
@@ -117,95 +168,5 @@ module ActiveSupport
Inflections.instance
end
end
-
- # Returns the plural form of the word in the string.
- #
- # Examples:
- # "post".pluralize # => "posts"
- # "octopus".pluralize # => "octopi"
- # "sheep".pluralize # => "sheep"
- # "words".pluralize # => "words"
- # "CamelOctopus".pluralize # => "CamelOctopi"
- def pluralize(word)
- result = word.to_s.dup
-
- if word.empty? || inflections.uncountables.include?(result.downcase)
- result
- else
- inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
- result
- end
- end
-
- # The reverse of +pluralize+, returns the singular form of a word in a string.
- #
- # Examples:
- # "posts".singularize # => "post"
- # "octopi".singularize # => "octopus"
- # "sheep".singularize # => "sheep"
- # "word".singularize # => "word"
- # "CamelOctopi".singularize # => "CamelOctopus"
- def singularize(word)
- result = word.to_s.dup
-
- if inflections.uncountables.any? { |inflection| result =~ /\b(#{inflection})\Z/i }
- result
- else
- inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
- result
- end
- end
-
- # Capitalizes the first word and turns underscores into spaces and strips a
- # trailing "_id", if any. Like +titleize+, this is meant for creating pretty output.
- #
- # Examples:
- # "employee_salary" # => "Employee salary"
- # "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
- end
-
- # Capitalizes all the words and replaces some characters in the string to create
- # a nicer looking title. +titleize+ is meant for creating pretty output. It is not
- # used in the Rails internals.
- #
- # +titleize+ is also aliased as as +titlecase+.
- #
- # Examples:
- # "man from the boondocks".titleize # => "Man From The Boondocks"
- # "x-men: the last stand".titleize # => "X Men: The Last Stand"
- def titleize(word)
- humanize(underscore(word)).gsub(/\b('?[a-z])/) { $1.capitalize }
- end
-
- # Create the name of a table like Rails does for models to table names. This method
- # uses the +pluralize+ method on the last word in the string.
- #
- # Examples
- # "RawScaledScorer".tableize # => "raw_scaled_scorers"
- # "egg_and_ham".tableize # => "egg_and_hams"
- # "fancyCategory".tableize # => "fancy_categories"
- def tableize(class_name)
- pluralize(underscore(class_name))
- end
-
- # Create a class name from a plural table name like Rails does for table names to models.
- # Note that this returns a string and not a Class. (To convert to an actual class
- # follow +classify+ with +constantize+.)
- #
- # Examples:
- # "egg_and_hams".classify # => "EggAndHam"
- # "posts".classify # => "Post"
- #
- # Singular names are not handled correctly:
- # "business".classify # => "Busines"
- def classify(table_name)
- # strip out any leading schema name
- camelize(singularize(table_name.to_s.sub(/.*\./, '')))
- end
end
end
diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb
index a2c4f7bfda..3d28d33f40 100644
--- a/activesupport/lib/active_support/inflector/methods.rb
+++ b/activesupport/lib/active_support/inflector/methods.rb
@@ -1,3 +1,5 @@
+require 'active_support/inflector/inflections'
+
module ActiveSupport
# The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without,
# and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept
@@ -10,6 +12,44 @@ module ActiveSupport
module Inflector
extend self
+ # Returns the plural form of the word in the string.
+ #
+ # Examples:
+ # "post".pluralize # => "posts"
+ # "octopus".pluralize # => "octopi"
+ # "sheep".pluralize # => "sheep"
+ # "words".pluralize # => "words"
+ # "CamelOctopus".pluralize # => "CamelOctopi"
+ def pluralize(word)
+ result = word.to_s.dup
+
+ if word.empty? || inflections.uncountables.include?(result.downcase)
+ result
+ else
+ inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
+ result
+ end
+ end
+
+ # The reverse of +pluralize+, returns the singular form of a word in a string.
+ #
+ # Examples:
+ # "posts".singularize # => "post"
+ # "octopi".singularize # => "octopus"
+ # "sheep".singularize # => "sheep"
+ # "word".singularize # => "word"
+ # "CamelOctopi".singularize # => "CamelOctopus"
+ def singularize(word)
+ result = word.to_s.dup
+
+ if inflections.uncountables.any? { |inflection| result =~ /\b(#{inflection})\Z/i }
+ result
+ else
+ inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
+ result
+ end
+ end
+
# By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+
# is set to <tt>:lower</tt> then +camelize+ produces lowerCamelCase.
#
@@ -25,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.
@@ -48,13 +90,66 @@ 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!
word
end
+ # Capitalizes the first word and turns underscores into spaces and strips a
+ # trailing "_id", if any. Like +titleize+, this is meant for creating pretty output.
+ #
+ # Examples:
+ # "employee_salary" # => "Employee salary"
+ # "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$/, "")
+ 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
+ # a nicer looking title. +titleize+ is meant for creating pretty output. It is not
+ # used in the Rails internals.
+ #
+ # +titleize+ is also aliased as as +titlecase+.
+ #
+ # Examples:
+ # "man from the boondocks".titleize # => "Man From The Boondocks"
+ # "x-men: the last stand".titleize # => "X Men: The Last Stand"
+ def titleize(word)
+ humanize(underscore(word)).gsub(/\b('?[a-z])/) { $1.capitalize }
+ end
+
+ # Create the name of a table like Rails does for models to table names. This method
+ # uses the +pluralize+ method on the last word in the string.
+ #
+ # Examples
+ # "RawScaledScorer".tableize # => "raw_scaled_scorers"
+ # "egg_and_ham".tableize # => "egg_and_hams"
+ # "fancyCategory".tableize # => "fancy_categories"
+ def tableize(class_name)
+ pluralize(underscore(class_name))
+ end
+
+ # Create a class name from a plural table name like Rails does for table names to models.
+ # Note that this returns a string and not a Class. (To convert to an actual class
+ # follow +classify+ with +constantize+.)
+ #
+ # Examples:
+ # "egg_and_hams".classify # => "EggAndHam"
+ # "posts".classify # => "Post"
+ #
+ # Singular names are not handled correctly:
+ # "business".classify # => "Busines"
+ def classify(table_name)
+ # strip out any leading schema name
+ camelize(singularize(table_name.to_s.sub(/.*\./, '')))
+ end
+
# Replaces underscores with dashes in the string.
#
# Example:
diff --git a/activesupport/lib/active_support/ordered_options.rb b/activesupport/lib/active_support/ordered_options.rb
index 8d8e6ebc58..bf81567d22 100644
--- a/activesupport/lib/active_support/ordered_options.rb
+++ b/activesupport/lib/active_support/ordered_options.rb
@@ -36,6 +36,10 @@ module ActiveSupport #:nodoc:
self[name]
end
end
+
+ def respond_to?(name)
+ true
+ end
end
class InheritableOptions < OrderedOptions
diff --git a/activesupport/lib/active_support/version.rb b/activesupport/lib/active_support/version.rb
index e135872bf6..bd8e7f907a 100644
--- a/activesupport/lib/active_support/version.rb
+++ b/activesupport/lib/active_support/version.rb
@@ -1,9 +1,9 @@
module ActiveSupport
module VERSION #:nodoc:
MAJOR = 3
- MINOR = 1
+ MINOR = 2
TINY = 0
- PRE = "rc1"
+ PRE = "beta"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
diff --git a/activesupport/test/configurable_test.rb b/activesupport/test/configurable_test.rb
index c6d8191298..2e5ea2c360 100644
--- a/activesupport/test/configurable_test.rb
+++ b/activesupport/test/configurable_test.rb
@@ -58,16 +58,26 @@ class ConfigurableActiveSupport < ActiveSupport::TestCase
child = Class.new(parent)
parent.config.bar = :foo
- assert !parent.config.respond_to?(:bar)
- assert !child.config.respond_to?(:bar)
- assert !child.new.config.respond_to?(:bar)
+ assert_method_not_defined parent.config, :bar
+ assert_method_not_defined child.config, :bar
+ assert_method_not_defined child.new.config, :bar
parent.config.compile_methods!
assert_equal :foo, parent.config.bar
assert_equal :foo, child.new.config.bar
- assert_respond_to parent.config, :bar
- assert_respond_to child.config, :bar
- assert_respond_to child.new.config, :bar
+ assert_method_defined parent.config, :bar
+ assert_method_defined child.config, :bar
+ assert_method_defined child.new.config, :bar
+ end
+
+ def assert_method_defined(object, method)
+ methods = object.public_methods.map(&:to_s)
+ assert methods.include?(method.to_s), "Expected #{methods.inspect} to include #{method.to_s.inspect}"
+ end
+
+ def assert_method_not_defined(object, method)
+ methods = object.public_methods.map(&:to_s)
+ assert !methods.include?(method.to_s), "Expected #{methods.inspect} to not include #{method.to_s.inspect}"
end
end
diff --git a/activesupport/test/core_ext/array_ext_test.rb b/activesupport/test/core_ext/array_ext_test.rb
index 0e5407bc35..e532010b18 100644
--- a/activesupport/test/core_ext/array_ext_test.rb
+++ b/activesupport/test/core_ext/array_ext_test.rb
@@ -456,8 +456,9 @@ class ArrayWrapperTests < Test::Unit::TestCase
assert_equal [o], Array.wrap(o)
end
- def test_wrap_returns_nil_if_to_ary_returns_nil
- assert_nil Array.wrap(NilToAry.new)
+ def test_wrap_returns_wrapped_if_to_ary_returns_nil
+ o = NilToAry.new
+ assert_equal [o], Array.wrap(o)
end
def test_wrap_does_not_complain_if_to_ary_does_not_return_an_array
diff --git a/activesupport/test/core_ext/module/attribute_accessor_test.rb b/activesupport/test/core_ext/module/attribute_accessor_test.rb
index 118fb070a0..29889b51e0 100644
--- a/activesupport/test/core_ext/module/attribute_accessor_test.rb
+++ b/activesupport/test/core_ext/module/attribute_accessor_test.rb
@@ -7,6 +7,7 @@ class ModuleAttributeAccessorTest < Test::Unit::TestCase
mattr_accessor :foo
mattr_accessor :bar, :instance_writer => false
mattr_reader :shaq, :instance_reader => false
+ mattr_accessor :camp, :instance_accessor => false
end
@class = Class.new
@class.instance_eval { include m }
@@ -37,4 +38,10 @@ class ModuleAttributeAccessorTest < Test::Unit::TestCase
assert_respond_to @module, :shaq
assert !@object.respond_to?(:shaq)
end
+
+ def test_should_not_create_instance_accessors
+ assert_respond_to @module, :camp
+ assert !@object.respond_to?(:camp)
+ assert !@object.respond_to?(:camp=)
+ end
end
diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb
index 7a8cda160d..0360cf2901 100644
--- a/activesupport/test/core_ext/string_ext_test.rb
+++ b/activesupport/test/core_ext/string_ext_test.rb
@@ -353,6 +353,10 @@ class OutputSafetyTest < ActiveSupport::TestCase
test "A fixnum is safe by default" do
assert 5.html_safe?
end
+
+ test "a float is safe by default" do
+ assert 5.7.html_safe?
+ end
test "An object is unsafe by default" do
assert !@object.html_safe?
diff --git a/activesupport/test/inflector_test.rb b/activesupport/test/inflector_test.rb
index 95f18126d4..b9e299af75 100644
--- a/activesupport/test/inflector_test.rb
+++ b/activesupport/test/inflector_test.rb
@@ -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))
@@ -148,8 +230,8 @@ class InflectorTest < Test::Unit::TestCase
end
def test_parameterize_with_custom_separator
- StringToParameterized.each do |some_string, parameterized_string|
- assert_equal(parameterized_string.gsub('-', '_'), ActiveSupport::Inflector.parameterize(some_string, '_'))
+ StringToParameterizeWithUnderscore.each do |some_string, parameterized_string|
+ assert_equal(parameterized_string, ActiveSupport::Inflector.parameterize(some_string, '_'))
end
end
diff --git a/activesupport/test/inflector_test_cases.rb b/activesupport/test/inflector_test_cases.rb
index ec9d92794c..0cb1f70657 100644
--- a/activesupport/test/inflector_test_cases.rb
+++ b/activesupport/test/inflector_test_cases.rb
@@ -168,6 +168,7 @@ module InflectorTestCases
StringToParameterizeWithNoSeparator = {
"Donald E. Knuth" => "donaldeknuth",
+ "With-some-dashes" => "with-some-dashes",
"Random text with *(bad)* characters" => "randomtextwithbadcharacters",
"Trailing bad characters!@#" => "trailingbadcharacters",
"!@#Leading bad characters" => "leadingbadcharacters",
@@ -179,6 +180,8 @@ module InflectorTestCases
StringToParameterizeWithUnderscore = {
"Donald E. Knuth" => "donald_e_knuth",
"Random text with *(bad)* characters" => "random_text_with_bad_characters",
+ "With-some-dashes" => "with-some-dashes",
+ "Retain_underscore" => "retain_underscore",
"Trailing bad characters!@#" => "trailing_bad_characters",
"!@#Leading bad characters" => "leading_bad_characters",
"Squeeze separators" => "squeeze_separators",
diff --git a/activesupport/test/time_zone_test.rb b/activesupport/test/time_zone_test.rb
index 49cefc6e82..3575175517 100644
--- a/activesupport/test/time_zone_test.rb
+++ b/activesupport/test/time_zone_test.rb
@@ -224,9 +224,9 @@ class TimeZoneTest < Test::Unit::TestCase
end
def test_formatted_offset_positive
- zone = ActiveSupport::TimeZone['Moscow']
- assert_equal "+03:00", zone.formatted_offset
- assert_equal "+0300", zone.formatted_offset(false)
+ zone = ActiveSupport::TimeZone['New Delhi']
+ assert_equal "+05:30", zone.formatted_offset
+ assert_equal "+0530", zone.formatted_offset(false)
end
def test_formatted_offset_negative
@@ -257,7 +257,7 @@ class TimeZoneTest < Test::Unit::TestCase
end
def test_to_s
- assert_equal "(GMT+03:00) Moscow", ActiveSupport::TimeZone['Moscow'].to_s
+ assert_equal "(GMT+05:30) New Delhi", ActiveSupport::TimeZone['New Delhi'].to_s
end
def test_all_sorted