diff options
Diffstat (limited to 'activesupport')
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 |