aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/lib/active_support/core_ext/array/conversions.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/enumerable.rb16
-rw-r--r--activesupport/lib/active_support/core_ext/hash/conversions.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/hash/deep_merge.rb9
-rw-r--r--activesupport/lib/active_support/core_ext/load_error.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb16
-rw-r--r--activesupport/lib/active_support/deprecation/method_wrappers.rb18
-rw-r--r--activesupport/lib/active_support/inflector.rb3
-rw-r--r--activesupport/lib/active_support/json/backends/yaml.rb5
-rw-r--r--activesupport/lib/active_support/memoizable.rb2
-rw-r--r--activesupport/lib/active_support/multibyte/chars.rb17
-rw-r--r--activesupport/test/core_ext/array_ext_test.rb7
-rw-r--r--activesupport/test/core_ext/date_ext_test.rb2
-rw-r--r--activesupport/test/core_ext/enumerable_test.rb9
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb19
-rw-r--r--activesupport/test/core_ext/time_ext_test.rb46
-rw-r--r--activesupport/test/dependencies_test.rb77
-rw-r--r--activesupport/test/deprecation_test.rb4
-rw-r--r--activesupport/test/flush_cache_on_private_memoization_test.rb44
-rw-r--r--activesupport/test/inflector_test.rb10
-rw-r--r--activesupport/test/isolation_test.rb2
-rw-r--r--activesupport/test/json/decoding_test.rb8
-rw-r--r--activesupport/test/multibyte_chars_test.rb15
23 files changed, 240 insertions, 94 deletions
diff --git a/activesupport/lib/active_support/core_ext/array/conversions.rb b/activesupport/lib/active_support/core_ext/array/conversions.rb
index 11846f265c..c53cf3f530 100644
--- a/activesupport/lib/active_support/core_ext/array/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/array/conversions.rb
@@ -159,6 +159,7 @@ class Array
raise "Not all elements respond to to_xml" unless all? { |e| e.respond_to? :to_xml }
require 'builder' unless defined?(Builder)
+ options = options.dup
options[:root] ||= all? { |e| e.is_a?(first.class) && first.class.to_s != "Hash" } ? ActiveSupport::Inflector.pluralize(ActiveSupport::Inflector.underscore(first.class.name)) : "records"
options[:children] ||= options[:root].singularize
options[:indent] ||= 2
diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb
index 434a32b29b..15a303cf04 100644
--- a/activesupport/lib/active_support/core_ext/enumerable.rb
+++ b/activesupport/lib/active_support/core_ext/enumerable.rb
@@ -55,12 +55,10 @@ module Enumerable
# [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
#
def sum(identity = 0, &block)
- return identity unless size > 0
-
if block_given?
- map(&block).sum
+ map(&block).sum(identity)
else
- inject { |sum, element| sum + element }
+ inject { |sum, element| sum + element } || identity
end
end
@@ -113,3 +111,13 @@ module Enumerable
!any?(&block)
end unless [].respond_to?(:none?)
end
+
+class Range #:nodoc:
+ # Optimize range sum to use arithmetic progression if a block is not given and
+ # we have a range of numeric values.
+ def sum(identity = 0)
+ return super if block_given? || !(first.instance_of?(Integer) && last.instance_of?(Integer))
+ actual_last = exclude_end? ? (last - 1) : last
+ (actual_last - first + 1) * (actual_last + first) / 2
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb
index 2a34874d08..bd9419e1a2 100644
--- a/activesupport/lib/active_support/core_ext/hash/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb
@@ -86,6 +86,7 @@ class Hash
def to_xml(options = {})
require 'builder' unless defined?(Builder)
+ options = options.dup
options[:indent] ||= 2
options.reverse_merge!({ :builder => Builder::XmlMarkup.new(:indent => options[:indent]),
:root => "hash" })
diff --git a/activesupport/lib/active_support/core_ext/hash/deep_merge.rb b/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
index ffde34a741..24d0a2a481 100644
--- a/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
+++ b/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
@@ -1,11 +1,12 @@
class Hash
# Returns a new hash with +self+ and +other_hash+ merged recursively.
def deep_merge(other_hash)
- merge(other_hash) do |key, oldval, newval|
- oldval = oldval.to_hash if oldval.respond_to?(:to_hash)
- newval = newval.to_hash if newval.respond_to?(:to_hash)
- oldval.is_a?( Hash ) && newval.is_a?( Hash ) ? oldval.deep_merge(newval) : newval
+ target = dup
+ other_hash.each_pair do |k,v|
+ tv = target[k]
+ target[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_merge(v) : v
end
+ target
end
# Returns a new hash with +self+ and +other_hash+ merged recursively.
diff --git a/activesupport/lib/active_support/core_ext/load_error.rb b/activesupport/lib/active_support/core_ext/load_error.rb
index f36a21818f..cc6287b100 100644
--- a/activesupport/lib/active_support/core_ext/load_error.rb
+++ b/activesupport/lib/active_support/core_ext/load_error.rb
@@ -20,7 +20,8 @@ class MissingSourceFile < LoadError #:nodoc:
REGEXPS = [
[/^no such file to load -- (.+)$/i, 1],
[/^Missing \w+ (file\s*)?([^\s]+.rb)$/i, 2],
- [/^Missing API definition file in (.+)$/i, 1]
+ [/^Missing API definition file in (.+)$/i, 1],
+ [/win32/, 0]
] unless defined?(REGEXPS)
end
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb
index b73c3b2c9b..4f3b869f50 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -158,7 +158,7 @@ class Time
alias :monday :beginning_of_week
alias :at_beginning_of_week :beginning_of_week
- # Returns a new Time representing the end of this week (Sunday, 23:59:59)
+ # Returns a new Time representing the end of this week, (end of Sunday)
def end_of_week
days_to_sunday = wday!=0 ? 7-wday : 0
(self + days_to_sunday.days).end_of_day
@@ -178,9 +178,9 @@ class Time
alias :at_midnight :beginning_of_day
alias :at_beginning_of_day :beginning_of_day
- # Returns a new Time representing the end of the day (23:59:59)
+ # Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9)
def end_of_day
- change(:hour => 23, :min => 59, :sec => 59)
+ change(:hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
end
# Returns a new Time representing the start of the month (1st of the month, 0:00)
@@ -190,11 +190,11 @@ class Time
end
alias :at_beginning_of_month :beginning_of_month
- # Returns a new Time representing the end of the month (last day of the month, 0:00)
+ # Returns a new Time representing the end of the month (end of the last day of the month)
def end_of_month
#self - ((self.mday-1).days + self.seconds_since_midnight)
last_day = ::Time.days_in_month(month, year)
- change(:day => last_day, :hour => 23, :min => 59, :sec => 59, :usec => 0)
+ change(:day => last_day, :hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
end
alias :at_end_of_month :end_of_month
@@ -204,7 +204,7 @@ class Time
end
alias :at_beginning_of_quarter :beginning_of_quarter
- # Returns a new Time representing the end of the quarter (last day of march, june, september, december, 23:59:59)
+ # Returns a new Time representing the end of the quarter (end of the last day of march, june, september, december)
def end_of_quarter
beginning_of_month.change(:month => [3, 6, 9, 12].detect { |m| m >= month }).end_of_month
end
@@ -216,9 +216,9 @@ class Time
end
alias :at_beginning_of_year :beginning_of_year
- # Returns a new Time representing the end of the year (31st of december, 23:59:59)
+ # Returns a new Time representing the end of the year (end of the 31st of december)
def end_of_year
- change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59)
+ change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
end
alias :at_end_of_year :end_of_year
diff --git a/activesupport/lib/active_support/deprecation/method_wrappers.rb b/activesupport/lib/active_support/deprecation/method_wrappers.rb
index b9eb539aa7..deb29a82b8 100644
--- a/activesupport/lib/active_support/deprecation/method_wrappers.rb
+++ b/activesupport/lib/active_support/deprecation/method_wrappers.rb
@@ -11,15 +11,15 @@ module ActiveSupport
method_names.each do |method_name|
target_module.alias_method_chain(method_name, :deprecation) do |target, punctuation|
target_module.module_eval(<<-end_eval, __FILE__, __LINE__ + 1)
- def #{target}_with_deprecation#{punctuation}(*args, &block) # def generate_secret_with_deprecation(*args, &block)
- ::ActiveSupport::Deprecation.warn( # ::ActiveSupport::Deprecation.warn(
- ::ActiveSupport::Deprecation.deprecated_method_warning( # ::ActiveSupport::Deprecation.deprecated_method_warning(
- :#{method_name}, # :generate_secret,
- #{options[method_name].inspect}), # "You should use ActiveSupport::SecureRandom.hex(64)"),
- caller # caller
- ) # )
- #{target}_without_deprecation#{punctuation}(*args, &block) # generate_secret_without_deprecation(*args, &block)
- end # end
+ def #{target}_with_deprecation#{punctuation}(*args, &block) # def generate_secret_with_deprecation(*args, &block)
+ ::ActiveSupport::Deprecation.warn( # ::ActiveSupport::Deprecation.warn(
+ ::ActiveSupport::Deprecation.deprecated_method_warning( # ::ActiveSupport::Deprecation.deprecated_method_warning(
+ :#{method_name}, # :generate_secret,
+ #{options[method_name].inspect}), # "You should use ActiveSupport::SecureRandom.hex(64)"),
+ caller # caller
+ ) # )
+ send(:#{target}_without_deprecation#{punctuation}, *args, &block) # send(:generate_secret_without_deprecation, *args, &block)
+ end # end
end_eval
end
end
diff --git a/activesupport/lib/active_support/inflector.rb b/activesupport/lib/active_support/inflector.rb
index 4ee96b13b4..67aea2782f 100644
--- a/activesupport/lib/active_support/inflector.rb
+++ b/activesupport/lib/active_support/inflector.rb
@@ -69,10 +69,13 @@ module ActiveSupport
@uncountables.delete(plural)
if singular[0,1].upcase == plural[0,1].upcase
plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
+ plural(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + plural[1..-1])
singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
else
plural(Regexp.new("#{singular[0,1].upcase}(?i)#{singular[1..-1]}$"), plural[0,1].upcase + plural[1..-1])
plural(Regexp.new("#{singular[0,1].downcase}(?i)#{singular[1..-1]}$"), plural[0,1].downcase + plural[1..-1])
+ plural(Regexp.new("#{plural[0,1].upcase}(?i)#{plural[1..-1]}$"), plural[0,1].upcase + plural[1..-1])
+ plural(Regexp.new("#{plural[0,1].downcase}(?i)#{plural[1..-1]}$"), plural[0,1].downcase + plural[1..-1])
singular(Regexp.new("#{plural[0,1].upcase}(?i)#{plural[1..-1]}$"), singular[0,1].upcase + singular[1..-1])
singular(Regexp.new("#{plural[0,1].downcase}(?i)#{plural[1..-1]}$"), singular[0,1].downcase + singular[1..-1])
end
diff --git a/activesupport/lib/active_support/json/backends/yaml.rb b/activesupport/lib/active_support/json/backends/yaml.rb
index 92dd31cfbc..59d2c37e40 100644
--- a/activesupport/lib/active_support/json/backends/yaml.rb
+++ b/activesupport/lib/active_support/json/backends/yaml.rb
@@ -20,7 +20,7 @@ module ActiveSupport
rescue ArgumentError => e
raise ParseError, "Invalid JSON string"
end
-
+
protected
# Ensure that ":" and "," are always followed by a space
def convert_json_to_yaml(json) #:nodoc:
@@ -42,6 +42,8 @@ module ActiveSupport
end
when ":",","
marks << scanner.pos - 1 unless quoting
+ when "\\"
+ scanner.skip(/\\/)
end
end
@@ -89,3 +91,4 @@ module ActiveSupport
end
end
end
+
diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb
index fa6db683d4..7724b9d88b 100644
--- a/activesupport/lib/active_support/memoizable.rb
+++ b/activesupport/lib/active_support/memoizable.rb
@@ -59,7 +59,7 @@ module ActiveSupport
def flush_cache(*syms, &block)
syms.each do |sym|
- methods.each do |m|
+ (methods + private_methods + protected_methods).each do |m|
if m.to_s =~ /^_unmemoized_(#{sym})/
ivar = ActiveSupport::Memoizable.memoized_ivar_for($1)
instance_variable_get(ivar).clear if instance_variable_defined?(ivar)
diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb
index 96ed35f0e0..64a35dca40 100644
--- a/activesupport/lib/active_support/multibyte/chars.rb
+++ b/activesupport/lib/active_support/multibyte/chars.rb
@@ -206,7 +206,22 @@ module ActiveSupport #:nodoc:
# 'Café périferôl'.mb_chars.index('ô') #=> 12
# 'Café périferôl'.mb_chars.index(/\w/u) #=> 0
def index(needle, offset=0)
- index = @wrapped_string.index(needle, offset)
+ wrapped_offset = self.first(offset).wrapped_string.length
+ index = @wrapped_string.index(needle, wrapped_offset)
+ index ? (self.class.u_unpack(@wrapped_string.slice(0...index)).size) : nil
+ end
+
+ # Returns the position _needle_ in the string, counting in
+ # codepoints, searching backward from _offset_ or the end of the
+ # string. Returns +nil+ if _needle_ isn't found.
+ #
+ # Example:
+ # 'Café périferôl'.mb_chars.rindex('é') #=> 6
+ # 'Café périferôl'.mb_chars.rindex(/\w/u) #=> 13
+ def rindex(needle, offset=nil)
+ offset ||= length
+ wrapped_offset = self.first(offset).wrapped_string.length
+ index = @wrapped_string.rindex(needle, wrapped_offset)
index ? (self.class.u_unpack(@wrapped_string.slice(0...index)).size) : nil
end
diff --git a/activesupport/test/core_ext/array_ext_test.rb b/activesupport/test/core_ext/array_ext_test.rb
index 24d33896ce..8198b9bd2c 100644
--- a/activesupport/test/core_ext/array_ext_test.rb
+++ b/activesupport/test/core_ext/array_ext_test.rb
@@ -302,6 +302,13 @@ class ArrayToXmlTests < Test::Unit::TestCase
xml = [].to_xml
assert_match(/type="array"\/>/, xml)
end
+
+ def test_to_xml_dups_options
+ options = {:skip_instruct => true}
+ [].to_xml(options)
+ # :builder, etc, shouldn't be added to options
+ assert_equal({:skip_instruct => true}, options)
+ end
end
class ArrayExtractOptionsTests < Test::Unit::TestCase
diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb
index 7fd551eaf3..8a7bae5fc6 100644
--- a/activesupport/test/core_ext/date_ext_test.rb
+++ b/activesupport/test/core_ext/date_ext_test.rb
@@ -196,7 +196,7 @@ class DateExtCalculationsTest < Test::Unit::TestCase
end
def test_end_of_day
- assert_equal Time.local(2005,2,21,23,59,59), Date.new(2005,2,21).end_of_day
+ assert_equal Time.local(2005,2,21,23,59,59,999999.999), Date.new(2005,2,21).end_of_day
end
def test_xmlschema
diff --git a/activesupport/test/core_ext/enumerable_test.rb b/activesupport/test/core_ext/enumerable_test.rb
index 885393815b..4170de3dce 100644
--- a/activesupport/test/core_ext/enumerable_test.rb
+++ b/activesupport/test/core_ext/enumerable_test.rb
@@ -1,5 +1,6 @@
require 'abstract_unit'
require 'active_support/core_ext/array'
+require 'active_support/core_ext/symbol'
require 'active_support/core_ext/enumerable'
Payment = Struct.new(:price)
@@ -60,6 +61,14 @@ class EnumerableTests < Test::Unit::TestCase
assert_equal Payment.new(0), [].sum(Payment.new(0))
end
+ def test_enumerable_sums
+ assert_equal 20, (1..4).sum { |i| i * 2 }
+ assert_equal 10, (1..4).sum
+ assert_equal 10, (1..4.5).sum
+ assert_equal 6, (1...4).sum
+ assert_equal 'abc', ('a'..'c').sum
+ end
+
def test_each_with_object
result = %w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase }
assert_equal({'foo' => 'FOO', 'bar' => 'BAR'}, result)
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index ece5466abb..eb4c37aaf0 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -265,6 +265,18 @@ class HashExtTest < Test::Unit::TestCase
assert_equal expected, hash_1
end
+ def test_deep_merge_on_indifferent_access
+ hash_1 = HashWithIndifferentAccess.new({ :a => "a", :b => "b", :c => { :c1 => "c1", :c2 => "c2", :c3 => { :d1 => "d1" } } })
+ hash_2 = HashWithIndifferentAccess.new({ :a => 1, :c => { :c1 => 2, :c3 => { :d2 => "d2" } } })
+ hash_3 = { :a => 1, :c => { :c1 => 2, :c3 => { :d2 => "d2" } } }
+ expected = { "a" => 1, "b" => "b", "c" => { "c1" => 2, "c2" => "c2", "c3" => { "d1" => "d1", "d2" => "d2" } } }
+ assert_equal expected, hash_1.deep_merge(hash_2)
+ assert_equal expected, hash_1.deep_merge(hash_3)
+
+ hash_1.deep_merge!(hash_2)
+ assert_equal expected, hash_1
+ end
+
def test_reverse_merge
defaults = { :a => "x", :b => "y", :c => 10 }.freeze
options = { :a => 1, :b => 2 }
@@ -880,6 +892,13 @@ class HashToXmlTest < Test::Unit::TestCase
assert_equal 30, alert_at.min
assert_equal 45, alert_at.sec
end
+
+ def test_to_xml_dups_options
+ options = {:skip_instruct => true}
+ {}.to_xml(options)
+ # :builder, etc, shouldn't be added to options
+ assert_equal({:skip_instruct => true}, options)
+ end
end
class QueryTest < Test::Unit::TestCase
diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb
index 1c2d0fbce4..f6003bc083 100644
--- a/activesupport/test/core_ext/time_ext_test.rb
+++ b/activesupport/test/core_ext/time_ext_test.rb
@@ -85,45 +85,45 @@ class TimeExtCalculationsTest < Test::Unit::TestCase
end
def test_end_of_day
- assert_equal Time.local(2007,8,12,23,59,59), Time.local(2007,8,12,10,10,10).end_of_day
+ assert_equal Time.local(2007,8,12,23,59,59,999999.999), Time.local(2007,8,12,10,10,10).end_of_day
with_env_tz 'US/Eastern' do
- assert_equal Time.local(2007,4,2,23,59,59), Time.local(2007,4,2,10,10,10).end_of_day, 'start DST'
- assert_equal Time.local(2007,10,29,23,59,59), Time.local(2007,10,29,10,10,10).end_of_day, 'ends DST'
+ assert_equal Time.local(2007,4,2,23,59,59,999999.999), Time.local(2007,4,2,10,10,10).end_of_day, 'start DST'
+ assert_equal Time.local(2007,10,29,23,59,59,999999.999), Time.local(2007,10,29,10,10,10).end_of_day, 'ends DST'
end
with_env_tz 'NZ' do
- assert_equal Time.local(2006,3,19,23,59,59), Time.local(2006,3,19,10,10,10).end_of_day, 'ends DST'
- assert_equal Time.local(2006,10,1,23,59,59), Time.local(2006,10,1,10,10,10).end_of_day, 'start DST'
+ assert_equal Time.local(2006,3,19,23,59,59,999999.999), Time.local(2006,3,19,10,10,10).end_of_day, 'ends DST'
+ assert_equal Time.local(2006,10,1,23,59,59,999999.999), Time.local(2006,10,1,10,10,10).end_of_day, 'start DST'
end
end
def test_end_of_week
- assert_equal Time.local(2008,1,6,23,59,59), Time.local(2007,12,31,10,10,10).end_of_week
- assert_equal Time.local(2007,9,2,23,59,59), Time.local(2007,8,27,0,0,0).end_of_week #monday
- assert_equal Time.local(2007,9,2,23,59,59), Time.local(2007,8,28,0,0,0).end_of_week #tuesday
- assert_equal Time.local(2007,9,2,23,59,59), Time.local(2007,8,29,0,0,0).end_of_week #wednesday
- assert_equal Time.local(2007,9,2,23,59,59), Time.local(2007,8,30,0,0,0).end_of_week #thursday
- assert_equal Time.local(2007,9,2,23,59,59), Time.local(2007,8,31,0,0,0).end_of_week #friday
- assert_equal Time.local(2007,9,2,23,59,59), Time.local(2007,9,01,0,0,0).end_of_week #saturday
- assert_equal Time.local(2007,9,2,23,59,59), Time.local(2007,9,02,0,0,0).end_of_week #sunday
+ assert_equal Time.local(2008,1,6,23,59,59,999999.999), Time.local(2007,12,31,10,10,10).end_of_week
+ assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,8,27,0,0,0).end_of_week #monday
+ assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,8,28,0,0,0).end_of_week #tuesday
+ assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,8,29,0,0,0).end_of_week #wednesday
+ assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,8,30,0,0,0).end_of_week #thursday
+ assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,8,31,0,0,0).end_of_week #friday
+ assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,9,01,0,0,0).end_of_week #saturday
+ assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,9,02,0,0,0).end_of_week #sunday
end
def test_end_of_month
- assert_equal Time.local(2005,3,31,23,59,59), Time.local(2005,3,20,10,10,10).end_of_month
- assert_equal Time.local(2005,2,28,23,59,59), Time.local(2005,2,20,10,10,10).end_of_month
- assert_equal Time.local(2005,4,30,23,59,59), Time.local(2005,4,20,10,10,10).end_of_month
+ assert_equal Time.local(2005,3,31,23,59,59,999999.999), Time.local(2005,3,20,10,10,10).end_of_month
+ assert_equal Time.local(2005,2,28,23,59,59,999999.999), Time.local(2005,2,20,10,10,10).end_of_month
+ assert_equal Time.local(2005,4,30,23,59,59,999999.999), Time.local(2005,4,20,10,10,10).end_of_month
end
def test_end_of_quarter
- assert_equal Time.local(2007,3,31,23,59,59), Time.local(2007,2,15,10,10,10).end_of_quarter
- assert_equal Time.local(2007,3,31,23,59,59), Time.local(2007,3,31,0,0,0).end_of_quarter
- assert_equal Time.local(2007,12,31,23,59,59), Time.local(2007,12,21,10,10,10).end_of_quarter
- assert_equal Time.local(2007,6,30,23,59,59), Time.local(2007,4,1,0,0,0).end_of_quarter
- assert_equal Time.local(2008,6,30,23,59,59), Time.local(2008,5,31,0,0,0).end_of_quarter
+ assert_equal Time.local(2007,3,31,23,59,59,999999.999), Time.local(2007,2,15,10,10,10).end_of_quarter
+ assert_equal Time.local(2007,3,31,23,59,59,999999.999), Time.local(2007,3,31,0,0,0).end_of_quarter
+ assert_equal Time.local(2007,12,31,23,59,59,999999.999), Time.local(2007,12,21,10,10,10).end_of_quarter
+ assert_equal Time.local(2007,6,30,23,59,59,999999.999), Time.local(2007,4,1,0,0,0).end_of_quarter
+ assert_equal Time.local(2008,6,30,23,59,59,999999.999), Time.local(2008,5,31,0,0,0).end_of_quarter
end
def test_end_of_year
- assert_equal Time.local(2007,12,31,23,59,59), Time.local(2007,2,22,10,10,10).end_of_year
- assert_equal Time.local(2007,12,31,23,59,59), Time.local(2007,12,31,10,10,10).end_of_year
+ assert_equal Time.local(2007,12,31,23,59,59,999999.999), Time.local(2007,2,22,10,10,10).end_of_year
+ assert_equal Time.local(2007,12,31,23,59,59,999999.999), Time.local(2007,12,31,10,10,10).end_of_year
end
def test_beginning_of_year
diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb
index 99c53924c2..97d70cf8c4 100644
--- a/activesupport/test/dependencies_test.rb
+++ b/activesupport/test/dependencies_test.rb
@@ -3,6 +3,7 @@ require 'pp'
require 'active_support/dependencies'
require 'active_support/core_ext/module/loading'
require 'active_support/core_ext/kernel/reporting'
+require 'active_support/core_ext/symbol/to_proc'
module ModuleWithMissing
mattr_accessor :missing_count
@@ -23,9 +24,11 @@ class DependenciesTest < Test::Unit::TestCase
def with_loading(*from)
old_mechanism, ActiveSupport::Dependencies.mechanism = ActiveSupport::Dependencies.mechanism, :load
- dir = File.dirname(__FILE__)
+ this_dir = File.dirname(__FILE__)
+ parent_dir = File.dirname(this_dir)
+ $LOAD_PATH.unshift(parent_dir) unless $LOAD_PATH.include?(parent_dir)
prior_load_paths = ActiveSupport::Dependencies.load_paths
- ActiveSupport::Dependencies.load_paths = from.collect { |f| "#{dir}/#{f}" }
+ ActiveSupport::Dependencies.load_paths = from.collect { |f| "#{this_dir}/#{f}" }
yield
ensure
ActiveSupport::Dependencies.load_paths = prior_load_paths
@@ -33,6 +36,10 @@ class DependenciesTest < Test::Unit::TestCase
ActiveSupport::Dependencies.explicitly_unloadable_constants = []
end
+ def with_autoloading_fixtures(&block)
+ with_loading 'autoloading_fixtures', &block
+ end
+
def test_tracking_loaded_files
require_dependency 'dependencies/service_one'
require_dependency 'dependencies/service_two'
@@ -129,7 +136,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_module_loading
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert_kind_of Module, A
assert_kind_of Class, A::B
assert_kind_of Class, A::C::D
@@ -138,7 +145,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_non_existing_const_raises_name_error
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert_raise(NameError) { DoesNotExist }
assert_raise(NameError) { NoModule::DoesNotExist }
assert_raise(NameError) { A::DoesNotExist }
@@ -147,49 +154,49 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_directories_manifest_as_modules_unless_const_defined
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert_kind_of Module, ModuleFolder
Object.__send__ :remove_const, :ModuleFolder
end
end
def test_module_with_nested_class
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert_kind_of Class, ModuleFolder::NestedClass
Object.__send__ :remove_const, :ModuleFolder
end
end
def test_module_with_nested_inline_class
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert_kind_of Class, ModuleFolder::InlineClass
Object.__send__ :remove_const, :ModuleFolder
end
end
def test_directories_may_manifest_as_nested_classes
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert_kind_of Class, ClassFolder
Object.__send__ :remove_const, :ClassFolder
end
end
def test_class_with_nested_class
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert_kind_of Class, ClassFolder::NestedClass
Object.__send__ :remove_const, :ClassFolder
end
end
def test_class_with_nested_inline_class
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert_kind_of Class, ClassFolder::InlineClass
Object.__send__ :remove_const, :ClassFolder
end
end
def test_class_with_nested_inline_subclass_of_parent
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert_kind_of Class, ClassFolder::ClassFolderSubclass
assert_kind_of Class, ClassFolder
assert_equal 'indeed', ClassFolder::ClassFolderSubclass::ConstantInClassFolder
@@ -198,7 +205,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_nested_class_can_access_sibling
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
sibling = ModuleFolder::NestedClass.class_eval "NestedSibling"
assert defined?(ModuleFolder::NestedSibling)
assert_equal ModuleFolder::NestedSibling, sibling
@@ -207,7 +214,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def failing_test_access_thru_and_upwards_fails
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert ! defined?(ModuleFolder)
assert_raise(NameError) { ModuleFolder::Object }
assert_raise(NameError) { ModuleFolder::NestedClass::Object }
@@ -216,7 +223,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_non_existing_const_raises_name_error_with_fully_qualified_name
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
begin
A::DoesNotExist.nil?
flunk "No raise!!"
@@ -294,7 +301,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_autoloaded?
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert ! ActiveSupport::Dependencies.autoloaded?("ModuleFolder")
assert ! ActiveSupport::Dependencies.autoloaded?("ModuleFolder::NestedClass")
@@ -373,7 +380,7 @@ class DependenciesTest < Test::Unit::TestCase
end
end_eval
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert_kind_of Integer, ::ModuleWithCustomConstMissing::B
assert_kind_of Module, ::ModuleWithCustomConstMissing::A
assert_kind_of String, ::ModuleWithCustomConstMissing::A::B
@@ -382,7 +389,7 @@ class DependenciesTest < Test::Unit::TestCase
def test_const_missing_should_not_double_load
$counting_loaded_times = 0
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
require_dependency '././counting_loader'
assert_equal 1, $counting_loaded_times
assert_raise(ArgumentError) { ActiveSupport::Dependencies.load_missing_constant Object, :CountingLoader }
@@ -396,7 +403,7 @@ class DependenciesTest < Test::Unit::TestCase
m.module_eval "def a() CountingLoader; end"
extend m
kls = nil
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
kls = nil
assert_nothing_raised { kls = a }
assert_equal "CountingLoader", kls.name
@@ -431,7 +438,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_load_once_paths_do_not_add_to_autoloaded_constants
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
ActiveSupport::Dependencies.load_once_paths = ActiveSupport::Dependencies.load_paths.dup
assert ! ActiveSupport::Dependencies.autoloaded?("ModuleFolder")
@@ -447,7 +454,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_application_should_special_case_application_controller
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
require_dependency 'application'
assert_equal 10, ApplicationController
assert ActiveSupport::Dependencies.autoloaded?(:ApplicationController)
@@ -455,7 +462,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_const_missing_on_kernel_should_fallback_to_object
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
kls = Kernel::E
assert_equal "E", kls.name
assert_equal kls.object_id, Kernel::E.object_id
@@ -463,14 +470,14 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_preexisting_constants_are_not_marked_as_autoloaded
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
require_dependency 'e'
assert ActiveSupport::Dependencies.autoloaded?(:E)
ActiveSupport::Dependencies.clear
end
Object.const_set :E, Class.new
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
require_dependency 'e'
assert ! ActiveSupport::Dependencies.autoloaded?(:E), "E shouldn't be marked autoloaded!"
ActiveSupport::Dependencies.clear
@@ -481,7 +488,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_unloadable
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
Object.const_set :M, Module.new
M.unloadable
@@ -495,14 +502,14 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_unloadable_should_fail_with_anonymous_modules
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
m = Module.new
assert_raise(ArgumentError) { m.unloadable }
end
end
def test_unloadable_should_return_change_flag
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
Object.const_set :M, Module.new
assert_equal true, M.unloadable
assert_equal false, M.unloadable
@@ -593,7 +600,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_file_with_multiple_constants_and_require_dependency
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert ! defined?(MultipleConstantFile)
assert ! defined?(SiblingConstant)
@@ -611,7 +618,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_file_with_multiple_constants_and_auto_loading
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert ! defined?(MultipleConstantFile)
assert ! defined?(SiblingConstant)
@@ -630,7 +637,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_nested_file_with_multiple_constants_and_require_dependency
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert ! defined?(ClassFolder::NestedClass)
assert ! defined?(ClassFolder::SiblingClass)
@@ -649,7 +656,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_nested_file_with_multiple_constants_and_auto_loading
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert ! defined?(ClassFolder::NestedClass)
assert ! defined?(ClassFolder::SiblingClass)
@@ -668,7 +675,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_autoload_doesnt_shadow_no_method_error_with_relative_constant
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert !defined?(::RaisesNoMethodError), "::RaisesNoMethodError is defined but it hasn't been referenced yet!"
2.times do
assert_raise(NoMethodError) { RaisesNoMethodError }
@@ -681,7 +688,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_autoload_doesnt_shadow_no_method_error_with_absolute_constant
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
assert !defined?(::RaisesNoMethodError), "::RaisesNoMethodError is defined but it hasn't been referenced yet!"
2.times do
assert_raise(NoMethodError) { ::RaisesNoMethodError }
@@ -694,7 +701,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_autoload_doesnt_shadow_error_when_mechanism_not_set_to_load
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
ActiveSupport::Dependencies.mechanism = :require
2.times do
assert_raise(NameError) { assert_equal 123, ::RaisesNameError::FooBarBaz }
@@ -703,7 +710,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_autoload_doesnt_shadow_name_error
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
Object.send(:remove_const, :RaisesNameError) if defined?(::RaisesNameError)
2.times do
begin
@@ -737,7 +744,7 @@ class DependenciesTest < Test::Unit::TestCase
end
def test_load_once_constants_should_not_be_unloaded
- with_loading 'autoloading_fixtures' do
+ with_autoloading_fixtures do
ActiveSupport::Dependencies.load_once_paths = ActiveSupport::Dependencies.load_paths
::A.to_s
assert defined?(A)
diff --git a/activesupport/test/deprecation_test.rb b/activesupport/test/deprecation_test.rb
index 73a1f9959c..a3ae39d071 100644
--- a/activesupport/test/deprecation_test.rb
+++ b/activesupport/test/deprecation_test.rb
@@ -25,6 +25,9 @@ class Deprecatee
def e; end
deprecate :a, :b, :c => :e, :d => "you now need to do something extra for this one"
+ def f=(v); end
+ deprecate :f=
+
module B
C = 1
end
@@ -133,6 +136,7 @@ class DeprecationTest < ActiveSupport::TestCase
def test_deprecation_without_explanation
assert_deprecated { @dtc.a }
assert_deprecated { @dtc.b }
+ assert_deprecated { @dtc.f = :foo }
end
def test_deprecation_with_alternate_method
diff --git a/activesupport/test/flush_cache_on_private_memoization_test.rb b/activesupport/test/flush_cache_on_private_memoization_test.rb
new file mode 100644
index 0000000000..ddbd05b0e0
--- /dev/null
+++ b/activesupport/test/flush_cache_on_private_memoization_test.rb
@@ -0,0 +1,44 @@
+require 'rubygems'
+require 'activesupport'
+require 'test/unit'
+
+class FlashCacheOnPrivateMemoizationTest < Test::Unit::TestCase
+ extend ActiveSupport::Memoizable
+
+ def test_public
+ assert_method_unmemoizable :pub
+ end
+
+ def test_protected
+ assert_method_unmemoizable :prot
+ end
+
+ def test_private
+ assert_method_unmemoizable :priv
+ end
+
+ def pub; rand end
+ memoize :pub
+
+ protected
+
+ def prot; rand end
+ memoize :prot
+
+ private
+
+ def priv; rand end
+ memoize :priv
+
+ def assert_method_unmemoizable(meth, message=nil)
+ full_message = build_message(message, "<?> not unmemoizable.\n", meth)
+ assert_block(full_message) do
+ a = send meth
+ b = send meth
+ unmemoize_all
+ c = send meth
+ a == b && a != c
+ end
+ end
+
+end \ No newline at end of file
diff --git a/activesupport/test/inflector_test.rb b/activesupport/test/inflector_test.rb
index 7d1554910e..76bdc0e973 100644
--- a/activesupport/test/inflector_test.rb
+++ b/activesupport/test/inflector_test.rb
@@ -256,6 +256,16 @@ class InflectorTest < Test::Unit::TestCase
end
end
+ Irregularities.each do |irregularity|
+ singular, plural = *irregularity
+ ActiveSupport::Inflector.inflections do |inflect|
+ define_method("test_pluralize_of_irregularity_#{plural}_should_be_the_same") do
+ inflect.irregular(singular, plural)
+ assert_equal plural, ActiveSupport::Inflector.pluralize(plural)
+ end
+ end
+ end
+
[ :all, [] ].each do |scope|
ActiveSupport::Inflector.inflections do |inflect|
define_method("test_clear_inflections_with_#{scope.kind_of?(Array) ? "no_arguments" : scope}") do
diff --git a/activesupport/test/isolation_test.rb b/activesupport/test/isolation_test.rb
index 5a1f285476..b83a7a0e49 100644
--- a/activesupport/test/isolation_test.rb
+++ b/activesupport/test/isolation_test.rb
@@ -73,7 +73,7 @@ else
File.open(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"), "w") {}
ENV["CHILD"] = "1"
- OUTPUT = `#{Gem.ruby} -I#{File.dirname(__FILE__)} #{File.expand_path(__FILE__)} -v`
+ OUTPUT = `#{Gem.ruby} -I#{File.dirname(__FILE__)} "#{File.expand_path(__FILE__)}" -v`
ENV.delete("CHILD")
def setup
diff --git a/activesupport/test/json/decoding_test.rb b/activesupport/test/json/decoding_test.rb
index 4129a4fab6..05e420ae36 100644
--- a/activesupport/test/json/decoding_test.rb
+++ b/activesupport/test/json/decoding_test.rb
@@ -14,10 +14,10 @@ class TestJSONDecoding < ActiveSupport::TestCase
%({"a": "a's, b's and c's", "b": "5,000"}) => {"a" => "a's, b's and c's", "b" => "5,000"},
# multibyte
%({"matzue": "松江", "asakusa": "浅草"}) => {"matzue" => "松江", "asakusa" => "浅草"},
- %({"a": "2007-01-01"}) => {'a' => Date.new(2007, 1, 1)},
- %({"a": "2007-01-01 01:12:34 Z"}) => {'a' => Time.utc(2007, 1, 1, 1, 12, 34)},
+ %({"a": "2007-01-01"}) => {'a' => Date.new(2007, 1, 1)},
+ %({"a": "2007-01-01 01:12:34 Z"}) => {'a' => Time.utc(2007, 1, 1, 1, 12, 34)},
# no time zone
- %({"a": "2007-01-01 01:12:34"}) => {'a' => "2007-01-01 01:12:34"},
+ %({"a": "2007-01-01 01:12:34"}) => {'a' => "2007-01-01 01:12:34"},
# needs to be *exact*
%({"a": " 2007-01-01 01:12:34 Z "}) => {'a' => " 2007-01-01 01:12:34 Z "},
%({"a": "2007-01-01 : it's your birthday"}) => {'a' => "2007-01-01 : it's your birthday"},
@@ -29,6 +29,7 @@ class TestJSONDecoding < ActiveSupport::TestCase
%({"a": null}) => {"a" => nil},
%({"a": true}) => {"a" => true},
%({"a": false}) => {"a" => false},
+ %q({"bad":"\\\\","trailing":""}) => {"bad" => "\\", "trailing" => ""},
%q({"a": "http:\/\/test.host\/posts\/1"}) => {"a" => "http://test.host/posts/1"},
%q({"a": "\u003cunicode\u0020escape\u003e"}) => {"a" => "<unicode escape>"},
%q({"a": "\\\\u0020skip double backslashes"}) => {"a" => "\\u0020skip double backslashes"},
@@ -83,3 +84,4 @@ class TestJSONDecoding < ActiveSupport::TestCase
assert_raise(ActiveSupport::JSON::ParseError) { ActiveSupport::JSON.decode(%({: 1})) }
end
end
+
diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb
index 661b33cc57..ed37a1a0da 100644
--- a/activesupport/test/multibyte_chars_test.rb
+++ b/activesupport/test/multibyte_chars_test.rb
@@ -1,5 +1,4 @@
# encoding: utf-8
-
require 'abstract_unit'
require 'multibyte_test_helpers'
@@ -184,7 +183,7 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase
end
def test_sortability
- words = %w(builder armor zebra).map(&:mb_chars).sort
+ words = %w(builder armor zebra).sort_by { |s| s.mb_chars }
assert_equal %w(armor builder zebra), words
end
@@ -231,7 +230,19 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase
assert_nil @chars.index('u')
assert_equal 0, @chars.index('こに')
assert_equal 2, @chars.index('ち')
+ assert_equal 2, @chars.index('ち', -2)
+ assert_equal nil, @chars.index('ち', -1)
assert_equal 3, @chars.index('わ')
+ assert_equal 5, 'ééxééx'.mb_chars.index('x', 4)
+ end
+
+ def test_rindex_should_return_character_offset
+ assert_nil @chars.rindex('u')
+ assert_equal 1, @chars.rindex('に')
+ assert_equal 2, @chars.rindex('ち', -2)
+ assert_nil @chars.rindex('ち', -3)
+ assert_equal 6, 'Café périferôl'.mb_chars.rindex('é')
+ assert_equal 13, 'Café périferôl'.mb_chars.rindex(/\w/u)
end
def test_indexed_insert_should_take_character_offsets