diff options
Diffstat (limited to 'activesupport')
17 files changed, 130 insertions, 21 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index d32c0f3aed..82921741b8 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -32,6 +32,9 @@ * Unicode database updated to 6.1.0. +* Adds `encode_big_decimal_as_string` option to force JSON serialization of BigDecimals as numeric instead + of wrapping them in strings for safety. + ## Rails 3.2.2 (March 1, 2012) ## diff --git a/activesupport/Rakefile b/activesupport/Rakefile index 822c9d98ae..822c9d98ae 100755..100644 --- a/activesupport/Rakefile +++ b/activesupport/Rakefile diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index b9f196d7a9..55791bfa56 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -280,7 +280,7 @@ module ActiveSupport end end if entry && entry.expired? - race_ttl = options[:race_condition_ttl].to_f + race_ttl = options[:race_condition_ttl].to_i if race_ttl and Time.now.to_f - entry.expires_at <= race_ttl entry.expires_at = Time.now + race_ttl write_entry(key, entry, :expires_in => race_ttl * 2) diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb index 8e6a3bc5a8..e7316b23b3 100644 --- a/activesupport/lib/active_support/cache/file_store.rb +++ b/activesupport/lib/active_support/cache/file_store.rb @@ -23,7 +23,7 @@ module ActiveSupport end def clear(options = nil) - root_dirs = Dir.entries(cache_path).reject{|f| f.in?(EXCLUDED_DIRS)} + root_dirs = Dir.entries(cache_path).reject{|f| f.in?(EXCLUDED_DIRS + [".gitkeep"])} FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)}) end diff --git a/activesupport/lib/active_support/core_ext/date_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_time/calculations.rb index 0e5aa5af10..020fa1a06d 100644 --- a/activesupport/lib/active_support/core_ext/date_time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date_time/calculations.rb @@ -91,6 +91,17 @@ class DateTime change(:hour => 23, :min => 59, :sec => 59) end + # Returns a new DateTime representing the start of the hour (hh:00:00) + def beginning_of_hour + change(:min => 0) + end + alias :at_beginning_of_hour :beginning_of_hour + + # Returns a new DateTime representing the end of the hour (hh:59:59) + def end_of_hour + change(:min => 59, :sec => 59) + end + # Adjusts DateTime to UTC by adding its offset value; offset is set to 0 # # Example: diff --git a/activesupport/lib/active_support/core_ext/hash/slice.rb b/activesupport/lib/active_support/core_ext/hash/slice.rb index fdeea4c148..b862b5ae2a 100644 --- a/activesupport/lib/active_support/core_ext/hash/slice.rb +++ b/activesupport/lib/active_support/core_ext/hash/slice.rb @@ -18,7 +18,7 @@ class Hash end # Replaces the hash with only the given keys. - # Returns a hash contained the removed key/value pairs + # Returns a hash containing the removed key/value pairs. # {:a => 1, :b => 2, :c => 3, :d => 4}.slice!(:a, :b) # => {:c => 3, :d => 4} def slice!(*keys) keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true) diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index 1434e186c3..a0f610d60c 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -257,6 +257,21 @@ class Time ) end + # Returns a new Time representing the start of the hour (x:00) + def beginning_of_hour + change(:min => 0) + end + alias :at_beginning_of_hour :beginning_of_hour + + # Returns a new Time representing the end of the hour, x:59:59.999999 (.999999999 in ruby1.9) + def end_of_hour + change( + :min => 59, + :sec => 59, + :usec => 999999.999 + ) + end + # Returns a new Time representing the start of the month (1st of the month, 0:00) def beginning_of_month #self - ((self.mday-1).days + self.seconds_since_midnight) diff --git a/activesupport/lib/active_support/deprecation/behaviors.rb b/activesupport/lib/active_support/deprecation/behaviors.rb index 73b6a42505..9102537810 100644 --- a/activesupport/lib/active_support/deprecation/behaviors.rb +++ b/activesupport/lib/active_support/deprecation/behaviors.rb @@ -6,24 +6,31 @@ module ActiveSupport # Whether to print a backtrace along with the warning. attr_accessor :debug - # Returns the set behavior or if one isn't set, defaults to +:stderr+ + # Returns the current behavior or if one isn't set, defaults to +:stderr+ def behavior @behavior ||= [DEFAULT_BEHAVIORS[:stderr]] end - # Sets the behavior to the specified value. Can be a single value or an array. + # Sets the behavior to the specified value. Can be a single value, array, or + # an object that responds to +call+. # - # Available behaviors: + # Available behaviors: # - # [+:stderr+] Print deprecations to +$stderror+ - # [+:log+] Send to +Rails.logger+ - # [+:notify+] Instrument using +ActiveSupport::Notifications+ - # [+:silence+] Do nothing + # [+stderr+] Log all deprecation warnings to +$stderr+. + # [+log+] Log all deprecation warnings to +Rails.logger+. + # [+notify] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+. + # [+silence+] Do nothing. # - # Examples + # Setting behaviors only affects deprecations that happen after boot time. + # Deprecation warnings raised by gems are not affected by this setting because + # they happen before Rails boots up. # # ActiveSupport::Deprecation.behavior = :stderr # ActiveSupport::Deprecation.behavior = [:stderr, :log] + # ActiveSupport::Deprecation.behavior = MyCustomHandler + # ActiveSupport::Deprecation.behavior = proc { |message, callstack| + # # custom stuff + # } def behavior=(behavior) @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || b } end diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb index 61876d89a9..4fcd32edf2 100644 --- a/activesupport/lib/active_support/inflector/methods.rb +++ b/activesupport/lib/active_support/inflector/methods.rb @@ -106,7 +106,7 @@ module ActiveSupport # 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+. + # +titleize+ is also aliased as +titlecase+. # # Examples: # "man from the boondocks".titleize # => "Man From The Boondocks" diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb index b2adfea273..ab12f3f454 100644 --- a/activesupport/lib/active_support/json/encoding.rb +++ b/activesupport/lib/active_support/json/encoding.rb @@ -17,6 +17,7 @@ module ActiveSupport class << self delegate :use_standard_json_time_format, :use_standard_json_time_format=, :escape_html_entities_in_json, :escape_html_entities_in_json=, + :encode_big_decimal_as_string, :encode_big_decimal_as_string=, :to => :'ActiveSupport::JSON::Encoding' end @@ -104,6 +105,9 @@ module ActiveSupport # If true, use ISO 8601 format for dates and times. Otherwise, fall back to the Active Support legacy format. attr_accessor :use_standard_json_time_format + # If false, serializes BigDecimal objects as numeric instead of wrapping them in a string + attr_accessor :encode_big_decimal_as_string + attr_accessor :escape_regex attr_reader :escape_html_entities_in_json @@ -133,6 +137,7 @@ module ActiveSupport self.use_standard_json_time_format = true self.escape_html_entities_in_json = false + self.encode_big_decimal_as_string = true end end end @@ -182,6 +187,12 @@ class Numeric def encode_json(encoder) to_s end #:nodoc: end +class Float + # Encoding Infinity or NaN to JSON should return "null". The default returns + # "Infinity" or "NaN" what breaks parsing the JSON. E.g. JSON.parse('[NaN]'). + def as_json(options = nil) finite? ? self : NilClass::AS_JSON end #:nodoc: +end + class BigDecimal # A BigDecimal would be naturally represented as a JSON number. Most libraries, # however, parse non-integer JSON numbers directly as floats. Clients using @@ -191,7 +202,15 @@ class BigDecimal # That's why a JSON string is returned. The JSON literal is not numeric, but if # the other end knows by contract that the data is supposed to be a BigDecimal, # it still has the chance to post-process the string and get the real value. - def as_json(options = nil) to_s end #:nodoc: + # + # Use ActiveSupport.use_standard_json_big_decimal_format = true to override this behaviour + def as_json(options = nil) #:nodoc: + if finite? + ActiveSupport.encode_big_decimal_as_string ? to_s : self + else + NilClass::AS_JSON + end + end end class Regexp diff --git a/activesupport/lib/active_support/rescuable.rb b/activesupport/lib/active_support/rescuable.rb index 85e84bc203..7aecdd11d3 100644 --- a/activesupport/lib/active_support/rescuable.rb +++ b/activesupport/lib/active_support/rescuable.rb @@ -48,6 +48,7 @@ module ActiveSupport # end # end # + # Exceptions raised inside exception handlers are not propagated up. def rescue_from(*klasses, &block) options = klasses.extract_options! diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb index 0baf9e1914..9543e50395 100644 --- a/activesupport/lib/active_support/values/time_zone.rb +++ b/activesupport/lib/active_support/values/time_zone.rb @@ -204,6 +204,7 @@ module ActiveSupport @current_period = nil end + # Returns the offset of this time zone from UTC in seconds. def utc_offset if @utc_offset @utc_offset diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index 5365713e6e..bb9ce23276 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -568,6 +568,13 @@ class FileStoreTest < ActiveSupport::TestCase include CacheDeleteMatchedBehavior include CacheIncrementDecrementBehavior + def test_clear + filepath = File.join(cache_dir, ".gitkeep") + FileUtils.touch(filepath) + @cache.clear + assert File.exist?(filepath) + end + def test_key_transformation key = @cache.send(:key_file_path, "views/index?id=1") assert_equal "views/index?id=1", @cache.send(:file_path_key, key) diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb index cd8cb5d18b..3da0825489 100644 --- a/activesupport/test/core_ext/date_time_ext_test.rb +++ b/activesupport/test/core_ext/date_time_ext_test.rb @@ -91,6 +91,14 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase assert_equal DateTime.civil(2005,2,4,23,59,59), DateTime.civil(2005,2,4,10,10,10).end_of_day end + def test_beginning_of_hour + assert_equal DateTime.civil(2005,2,4,19,0,0), DateTime.civil(2005,2,4,19,30,10).beginning_of_hour + end + + def test_end_of_hour + assert_equal DateTime.civil(2005,2,4,19,59,59), DateTime.civil(2005,2,4,19,30,10).end_of_hour + end + def test_beginning_of_month assert_equal DateTime.civil(2005,2,1,0,0,0), DateTime.civil(2005,2,22,10,10,10).beginning_of_month end diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb index c542acca68..4c1ed4b1ae 100644 --- a/activesupport/test/core_ext/time_ext_test.rb +++ b/activesupport/test/core_ext/time_ext_test.rb @@ -93,6 +93,10 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase end end + def test_beginning_of_hour + assert_equal Time.local(2005,2,4,19,0,0), Time.local(2005,2,4,19,30,10).beginning_of_hour + end + def test_beginning_of_month assert_equal Time.local(2005,2,1,0,0,0), Time.local(2005,2,22,10,10,10).beginning_of_month end @@ -127,6 +131,10 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase 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_hour + assert_equal Time.local(2005,2,4,19,59,59,999999.999), Time.local(2005,2,4,19,30,10).end_of_hour + end + def test_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 diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb index 00a03de875..b62337e31b 100644 --- a/activesupport/test/core_ext/time_with_zone_test.rb +++ b/activesupport/test/core_ext/time_with_zone_test.rb @@ -191,7 +191,7 @@ class TimeWithZoneTest < ActiveSupport::TestCase end end - def future_with_time_current_as_time_with_zone + def test_future_with_time_current_as_time_with_zone twz = ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45) ) Time.stubs(:current).returns(twz) assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,44)).future? @@ -483,36 +483,50 @@ class TimeWithZoneTest < ActiveSupport::TestCase assert_equal "Fri, 31 Dec 1999 19:00:30 EST -05:00", @twz.advance(:seconds => 30).inspect end - def beginning_of_year + def test_beginning_of_year assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect assert_equal "Fri, 01 Jan 1999 00:00:00 EST -05:00", @twz.beginning_of_year.inspect end - def end_of_year + def test_end_of_year assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect assert_equal "Fri, 31 Dec 1999 23:59:59 EST -05:00", @twz.end_of_year.inspect end - def beginning_of_month + def test_beginning_of_month assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect - assert_equal "Fri, 01 Dec 1999 00:00:00 EST -05:00", @twz.beginning_of_month.inspect + assert_equal "Wed, 01 Dec 1999 00:00:00 EST -05:00", @twz.beginning_of_month.inspect end - def end_of_month + def test_end_of_month assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect assert_equal "Fri, 31 Dec 1999 23:59:59 EST -05:00", @twz.end_of_month.inspect end - def beginning_of_day + def test_beginning_of_day assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect assert_equal "Fri, 31 Dec 1999 00:00:00 EST -05:00", @twz.beginning_of_day.inspect end - def end_of_day + def test_end_of_day assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect assert_equal "Fri, 31 Dec 1999 23:59:59 EST -05:00", @twz.end_of_day.inspect end + def test_beginning_of_hour + utc = Time.utc(2000, 1, 1, 0, 30) + twz = ActiveSupport::TimeWithZone.new(utc, @time_zone) + assert_equal "Fri, 31 Dec 1999 19:30:00 EST -05:00", twz.inspect + assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", twz.beginning_of_hour.inspect + end + + def test_end_of_hour + utc = Time.utc(2000, 1, 1, 0, 30) + twz = ActiveSupport::TimeWithZone.new(utc, @time_zone) + assert_equal "Fri, 31 Dec 1999 19:30:00 EST -05:00", twz.inspect + assert_equal "Fri, 31 Dec 1999 19:59:59 EST -05:00", twz.end_of_hour.inspect + end + def test_since assert_equal "Fri, 31 Dec 1999 19:00:01 EST -05:00", @twz.since(1).inspect end diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index a2e61d88d5..0566ebf291 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -27,6 +27,10 @@ class TestJSONEncoding < ActiveSupport::TestCase NilTests = [[ nil, %(null) ]] NumericTests = [[ 1, %(1) ], [ 2.5, %(2.5) ], + [ 0.0/0.0, %(null) ], + [ 1.0/0.0, %(null) ], + [ -1.0/0.0, %(null) ], + [ BigDecimal('0.0')/BigDecimal('0.0'), %(null) ], [ BigDecimal('2.5'), %("#{BigDecimal('2.5').to_s}") ]] StringTests = [[ 'this is the <string>', %("this is the \\u003Cstring\\u003E")], @@ -270,6 +274,17 @@ class TestJSONEncoding < ActiveSupport::TestCase JSON.parse(json_string_and_date)) end + def test_opt_out_big_decimal_string_serialization + big_decimal = BigDecimal('2.5') + + begin + ActiveSupport.encode_big_decimal_as_string = false + assert_equal big_decimal.to_s, big_decimal.to_json + ensure + ActiveSupport.encode_big_decimal_as_string = true + end + end + protected def object_keys(json_object) |