aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authorrick <rick@spacemonkey.local>2008-04-23 12:14:59 -0700
committerrick <rick@spacemonkey.local>2008-04-23 12:14:59 -0700
commiteacb5cf0cab6447db78085c8bda6c94dd329ce6b (patch)
treedf4bc7789c4d1fe83085b725be0d1fe4a6223880 /activesupport
parent69d29e80f76079262f2e98e350592be1cfdfcd1e (diff)
parent6c1c16bfd9eb865dffa68c12c7df66d5a59a8714 (diff)
downloadrails-eacb5cf0cab6447db78085c8bda6c94dd329ce6b.tar.gz
rails-eacb5cf0cab6447db78085c8bda6c94dd329ce6b.tar.bz2
rails-eacb5cf0cab6447db78085c8bda6c94dd329ce6b.zip
Merge branch 'master' of git@github.com:rails/rails
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG2
-rw-r--r--activesupport/lib/active_support/callbacks.rb40
-rw-r--r--activesupport/lib/active_support/core_ext/date_time/conversions.rb13
-rw-r--r--activesupport/lib/active_support/core_ext/enumerable.rb5
-rw-r--r--activesupport/lib/active_support/core_ext/object/instance_variables.rb8
-rw-r--r--activesupport/lib/active_support/core_ext/string.rb13
-rw-r--r--activesupport/lib/active_support/core_ext/string/access.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/string/iterators.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/string/starts_ends_with.rb16
-rw-r--r--activesupport/lib/active_support/core_ext/string/unicode.rb9
-rw-r--r--activesupport/lib/active_support/core_ext/symbol.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/time/zones.rb5
-rw-r--r--activesupport/lib/active_support/duration.rb6
-rw-r--r--activesupport/test/callbacks_test.rb31
-rw-r--r--activesupport/test/core_ext/duration_test.rb42
-rw-r--r--activesupport/test/core_ext/time_with_zone_test.rb24
16 files changed, 179 insertions, 43 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index cfdefed91e..a911361d3b 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Duration #since and #ago with no argument (e.g., 5.days.ago) return TimeWithZone when config.time_zone is set. Introducing Time.current, which returns Time.zone.now if config.time_zone is set, otherwise just returns Time.now [Geoff Buesing]
+
* Time#since behaves correctly when passed a Duration. Closes #11527 [kemiller]
* Add #getutc alias for DateTime#utc [Geoff Buesing]
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index 329cc2fdc7..9c59b7ac76 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -96,17 +96,25 @@ module ActiveSupport
end
end
- def find_callback(callback, &block)
+ def |(chain)
+ if chain.is_a?(CallbackChain)
+ chain.each { |callback| self | callback }
+ else
+ if (found_callback = find(chain)) && (index = index(chain))
+ self[index] = chain
+ else
+ self << chain
+ end
+ end
+ self
+ end
+
+ def find(callback, &block)
select { |c| c == callback && (!block_given? || yield(c)) }.first
end
- def replace_or_append_callback(callback)
- if found_callback = find_callback(callback)
- index = index(found_callback)
- self[index] = callback
- else
- self << callback
- end
+ def delete(callback)
+ super(callback.is_a?(Callback) ? callback : find(callback))
end
private
@@ -216,8 +224,8 @@ module ActiveSupport
end
end
- # Runs all the callbacks defined for the given options.
- #
+ # Runs all the callbacks defined for the given options.
+ #
# If a block is given it will be called after each callback receiving as arguments:
#
# * the result from the callback
@@ -228,31 +236,31 @@ module ActiveSupport
# Example:
# class Storage
# include ActiveSupport::Callbacks
- #
+ #
# define_callbacks :before_save, :after_save
# end
- #
+ #
# class ConfigStorage < Storage
# before_save :pass
# before_save :pass
# before_save :stop
# before_save :pass
- #
+ #
# def pass
# puts "pass"
# end
- #
+ #
# def stop
# puts "stop"
# return false
# end
- #
+ #
# def save
# result = run_callbacks(:before_save) { |result, object| result == false }
# puts "- save" if result
# end
# end
- #
+ #
# config = ConfigStorage.new
# config.save
#
diff --git a/activesupport/lib/active_support/core_ext/date_time/conversions.rb b/activesupport/lib/active_support/core_ext/date_time/conversions.rb
index aa9caf1774..c0175a5f28 100644
--- a/activesupport/lib/active_support/core_ext/date_time/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/conversions.rb
@@ -3,17 +3,22 @@ module ActiveSupport #:nodoc:
module DateTime #:nodoc:
# Converting datetimes to formatted strings, dates, and times.
module Conversions
- def self.included(base) #:nodoc:
+ def self.append_features(base) #:nodoc:
base.class_eval do
- alias_method :to_default_s, :to_s if instance_methods.include?(:to_s)
- alias_method :to_s, :to_formatted_s
alias_method :default_inspect, :inspect
- alias_method :inspect, :readable_inspect
+ alias_method :to_default_s, :to_s unless (instance_methods(false) & [:to_s, 'to_s']).empty?
# Ruby 1.9 has DateTime#to_time which internally relies on Time. We define our own #to_time which allows
# DateTimes outside the range of what can be created with Time.
remove_method :to_time if instance_methods.include?(:to_time)
end
+
+ super
+
+ base.class_eval do
+ alias_method :to_s, :to_formatted_s
+ alias_method :inspect, :readable_inspect
+ end
end
# Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.
diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb
index 1b96eb166a..8f111e29fc 100644
--- a/activesupport/lib/active_support/core_ext/enumerable.rb
+++ b/activesupport/lib/active_support/core_ext/enumerable.rb
@@ -1,4 +1,7 @@
module Enumerable
+ # Ruby 1.8.7 introduces group_by, but the result isn't ordered. Override it.
+ remove_method(:group_by) if [].respond_to?(:group_by) && RUBY_VERSION < '1.9'
+
# Collect an enumerable into sets, grouped by the result of a block. Useful,
# for example, for grouping records by date.
#
@@ -19,7 +22,7 @@ module Enumerable
(grouped[yield(element)] ||= []) << element
grouped
end
- end if RUBY_VERSION < '1.9'
+ end unless [].respond_to?(:group_by)
# Calculates a sum from the elements. Examples:
#
diff --git a/activesupport/lib/active_support/core_ext/object/instance_variables.rb b/activesupport/lib/active_support/core_ext/object/instance_variables.rb
index ee1010b250..9f1d4ed2aa 100644
--- a/activesupport/lib/active_support/core_ext/object/instance_variables.rb
+++ b/activesupport/lib/active_support/core_ext/object/instance_variables.rb
@@ -33,8 +33,12 @@ class Object
# end
#
# C.new(0, 1).instance_variable_names # => ["@y", "@x"]
- def instance_variable_names
- instance_variables.map(&:to_s)
+ if RUBY_VERSION >= '1.9'
+ def instance_variable_names
+ instance_variables.map(&:to_s)
+ end
+ else
+ alias_method :instance_variable_names, :instance_variables
end
# Copies the instance variables of +object+ into +self+.
diff --git a/activesupport/lib/active_support/core_ext/string.rb b/activesupport/lib/active_support/core_ext/string.rb
index a83474f278..25386af70a 100644
--- a/activesupport/lib/active_support/core_ext/string.rb
+++ b/activesupport/lib/active_support/core_ext/string.rb
@@ -2,7 +2,7 @@ require 'active_support/core_ext/string/inflections'
require 'active_support/core_ext/string/conversions'
require 'active_support/core_ext/string/access'
require 'active_support/core_ext/string/starts_ends_with'
-require 'active_support/core_ext/string/iterators' unless 'test'.respond_to?(:each_char)
+require 'active_support/core_ext/string/iterators'
require 'active_support/core_ext/string/unicode'
require 'active_support/core_ext/string/xchar'
require 'active_support/core_ext/string/filters'
@@ -12,14 +12,7 @@ class String #:nodoc:
include ActiveSupport::CoreExtensions::String::Conversions
include ActiveSupport::CoreExtensions::String::Filters
include ActiveSupport::CoreExtensions::String::Inflections
- if RUBY_VERSION < '1.9'
- include ActiveSupport::CoreExtensions::String::StartsEndsWith
- else
- alias starts_with? start_with?
- alias ends_with? end_with?
- end
- if defined? ActiveSupport::CoreExtensions::String::Iterators
- include ActiveSupport::CoreExtensions::String::Iterators
- end
+ include ActiveSupport::CoreExtensions::String::StartsEndsWith
+ include ActiveSupport::CoreExtensions::String::Iterators
include ActiveSupport::CoreExtensions::String::Unicode
end
diff --git a/activesupport/lib/active_support/core_ext/string/access.rb b/activesupport/lib/active_support/core_ext/string/access.rb
index 89999ff136..1a949c0b77 100644
--- a/activesupport/lib/active_support/core_ext/string/access.rb
+++ b/activesupport/lib/active_support/core_ext/string/access.rb
@@ -1,7 +1,7 @@
module ActiveSupport #:nodoc:
module CoreExtensions #:nodoc:
module String #:nodoc:
- if RUBY_VERSION < '1.9'
+ unless '1.9'.respond_to?(:force_encoding)
# Makes it easier to access parts of a string, such as specific characters and substrings.
module Access
# Returns the character at the +position+ treating the string as an array (where 0 is the first character).
diff --git a/activesupport/lib/active_support/core_ext/string/iterators.rb b/activesupport/lib/active_support/core_ext/string/iterators.rb
index 73114d9d5f..66a08a5cd0 100644
--- a/activesupport/lib/active_support/core_ext/string/iterators.rb
+++ b/activesupport/lib/active_support/core_ext/string/iterators.rb
@@ -5,6 +5,10 @@ module ActiveSupport #:nodoc:
module String #:nodoc:
# Custom string iterators
module Iterators
+ def self.append_features(base)
+ super unless '1.9'.respond_to?(:each_char)
+ end
+
# Yields a single-character string for each character in the string.
# When $KCODE = 'UTF8', multi-byte characters are yielded appropriately.
def each_char
diff --git a/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb b/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb
index 3960669798..09f9a188b5 100644
--- a/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb
+++ b/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb
@@ -3,10 +3,18 @@ module ActiveSupport #:nodoc:
module String #:nodoc:
# Additional string tests.
module StartsEndsWith
- def self.included(base)
- base.class_eval do
- alias_method :start_with?, :starts_with?
- alias_method :end_with?, :ends_with?
+ def self.append_features(base)
+ if '1.8.7 and up'.respond_to?(:start_with?)
+ base.class_eval do
+ alias_method :starts_with?, :start_with?
+ alias_method :ends_with?, :end_with?
+ end
+ else
+ super
+ base.class_eval do
+ alias_method :start_with?, :starts_with?
+ alias_method :end_with?, :ends_with?
+ end
end
end
diff --git a/activesupport/lib/active_support/core_ext/string/unicode.rb b/activesupport/lib/active_support/core_ext/string/unicode.rb
index 0e9770af25..ba16d4d866 100644
--- a/activesupport/lib/active_support/core_ext/string/unicode.rb
+++ b/activesupport/lib/active_support/core_ext/string/unicode.rb
@@ -1,9 +1,16 @@
module ActiveSupport #:nodoc:
module CoreExtensions #:nodoc:
module String #:nodoc:
- if RUBY_VERSION < '1.9'
+ unless '1.9'.respond_to?(:force_encoding)
# Define methods for handling unicode data.
module Unicode
+ def self.append_features(base)
+ if '1.8.7'.respond_to?(:chars)
+ base.class_eval { remove_method :chars }
+ end
+ super
+ end
+
# +chars+ is a Unicode safe proxy for string methods. It creates and returns an instance of the
# ActiveSupport::Multibyte::Chars class which encapsulates the original string. A Unicode safe version of all
# the String methods are defined on this proxy class. Undefined methods are forwarded to String, so all of the
diff --git a/activesupport/lib/active_support/core_ext/symbol.rb b/activesupport/lib/active_support/core_ext/symbol.rb
index 54f541ad9a..e4ac443809 100644
--- a/activesupport/lib/active_support/core_ext/symbol.rb
+++ b/activesupport/lib/active_support/core_ext/symbol.rb
@@ -1,4 +1,4 @@
-unless :test.respond_to?(:to_proc)
+unless :to_proc.respond_to?(:to_proc)
class Symbol
# Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:
#
diff --git a/activesupport/lib/active_support/core_ext/time/zones.rb b/activesupport/lib/active_support/core_ext/time/zones.rb
index d2b95698e5..3ffc71407c 100644
--- a/activesupport/lib/active_support/core_ext/time/zones.rb
+++ b/activesupport/lib/active_support/core_ext/time/zones.rb
@@ -35,6 +35,11 @@ module ActiveSupport #:nodoc:
::Time.zone = old_zone
end
+ # Returns Time.zone.now when config.time_zone is set, otherwise just returns Time.now.
+ def current
+ ::Time.zone_default ? ::Time.zone.now : ::Time.now
+ end
+
private
def get_zone(time_zone)
return time_zone if time_zone.nil? || time_zone.is_a?(TimeZone)
diff --git a/activesupport/lib/active_support/duration.rb b/activesupport/lib/active_support/duration.rb
index ff51b49dcf..8eae85d38e 100644
--- a/activesupport/lib/active_support/duration.rb
+++ b/activesupport/lib/active_support/duration.rb
@@ -51,14 +51,14 @@ module ActiveSupport
# Calculates a new Time or Date that is as far in the future
# as this Duration represents.
- def since(time = ::Time.now)
+ def since(time = ::Time.current)
sum(1, time)
end
alias :from_now :since
# Calculates a new Time or Date that is as far in the past
# as this Duration represents.
- def ago(time = ::Time.now)
+ def ago(time = ::Time.current)
sum(-1, time)
end
alias :until :ago
@@ -73,7 +73,7 @@ module ActiveSupport
protected
- def sum(sign, time = ::Time.now) #:nodoc:
+ def sum(sign, time = ::Time.current) #:nodoc:
parts.inject(time) do |t,(type,number)|
if t.acts_like?(:time) || t.acts_like?(:date)
if type == :seconds
diff --git a/activesupport/test/callbacks_test.rb b/activesupport/test/callbacks_test.rb
index 3f8cb7f01a..7f71ca2262 100644
--- a/activesupport/test/callbacks_test.rb
+++ b/activesupport/test/callbacks_test.rb
@@ -96,6 +96,8 @@ class ConditionalCallbackTest < Test::Unit::TestCase
end
class CallbackTest < Test::Unit::TestCase
+ include ActiveSupport::Callbacks
+
def test_eql
callback = Callback.new(:before, :save, :identifier => :lifesaver)
assert callback.eql?(Callback.new(:before, :save, :identifier => :lifesaver))
@@ -115,3 +117,32 @@ class CallbackTest < Test::Unit::TestCase
assert_equal({}, a.options)
end
end
+
+class CallbackChainTest < Test::Unit::TestCase
+ include ActiveSupport::Callbacks
+
+ def setup
+ @chain = CallbackChain.build(:make, :bacon, :lettuce, :tomato)
+ end
+
+ def test_build
+ assert_equal 3, @chain.size
+ assert_equal [:bacon, :lettuce, :tomato], @chain.map(&:method)
+ end
+
+ def test_find
+ assert_equal :bacon, @chain.find(:bacon).method
+ end
+
+ def test_union
+ assert_equal [:bacon, :lettuce, :tomato], (@chain | Callback.new(:make, :bacon)).map(&:method)
+ assert_equal [:bacon, :lettuce, :tomato, :turkey], (@chain | CallbackChain.build(:make, :bacon, :lettuce, :tomato, :turkey)).map(&:method)
+ assert_equal [:bacon, :lettuce, :tomato, :turkey, :mayo], (@chain | Callback.new(:make, :mayo)).map(&:method)
+ end
+
+ def test_delete
+ assert_equal [:bacon, :lettuce, :tomato], @chain.map(&:method)
+ @chain.delete(:bacon)
+ assert_equal [:lettuce, :tomato], @chain.map(&:method)
+ end
+end
diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb
index df878f917b..7b17fe71db 100644
--- a/activesupport/test/core_ext/duration_test.rb
+++ b/activesupport/test/core_ext/duration_test.rb
@@ -29,4 +29,46 @@ class DurationTest < Test::Unit::TestCase
flunk("ArgumentError should be raised, but we got #{$!.class} instead")
end
end
+
+ uses_mocha 'TestDurationSinceAndAgoWithCurrentTime' do
+ def test_since_and_ago_anchored_to_time_now_when_time_zone_default_not_set
+ Time.zone_default = nil
+ with_env_tz 'US/Eastern' do
+ Time.stubs(:now).returns Time.local(2000)
+ # since
+ assert_equal false, 5.seconds.since.is_a?(ActiveSupport::TimeWithZone)
+ assert_equal Time.local(2000,1,1,0,0,5), 5.seconds.since
+ # ago
+ assert_equal false, 5.seconds.ago.is_a?(ActiveSupport::TimeWithZone)
+ assert_equal Time.local(1999,12,31,23,59,55), 5.seconds.ago
+ end
+ end
+
+ def test_since_and_ago_anchored_to_time_zone_now_when_time_zone_default_set
+ silence_warnings do # silence warnings raised by tzinfo gem
+ Time.zone_default = TimeZone['Eastern Time (US & Canada)']
+ with_env_tz 'US/Eastern' do
+ Time.stubs(:now).returns Time.local(2000)
+ # since
+ assert_equal true, 5.seconds.since.is_a?(ActiveSupport::TimeWithZone)
+ assert_equal Time.utc(2000,1,1,0,0,5), 5.seconds.since.time
+ assert_equal 'Eastern Time (US & Canada)', 5.seconds.since.time_zone.name
+ # ago
+ assert_equal true, 5.seconds.ago.is_a?(ActiveSupport::TimeWithZone)
+ assert_equal Time.utc(1999,12,31,23,59,55), 5.seconds.ago.time
+ assert_equal 'Eastern Time (US & Canada)', 5.seconds.ago.time_zone.name
+ end
+ end
+ ensure
+ Time.zone_default = nil
+ end
+ end
+
+ protected
+ def with_env_tz(new_tz = 'US/Eastern')
+ old_tz, ENV['TZ'] = ENV['TZ'], new_tz
+ yield
+ ensure
+ old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+ end
end
diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb
index efab8a24c8..df70e82c1d 100644
--- a/activesupport/test/core_ext/time_with_zone_test.rb
+++ b/activesupport/test/core_ext/time_with_zone_test.rb
@@ -627,6 +627,30 @@ class TimeWithZoneMethodsForTimeAndDateTimeTest < Test::Unit::TestCase
assert_equal nil, Time.zone
end
+ uses_mocha 'TestTimeCurrent' do
+ def test_current_returns_time_now_when_zone_default_not_set
+ with_env_tz 'US/Eastern' do
+ Time.stubs(:now).returns Time.local(2000)
+ assert_equal false, Time.current.is_a?(ActiveSupport::TimeWithZone)
+ assert_equal Time.local(2000), Time.current
+ end
+ end
+
+ def test_current_returns_time_zone_now_when_zone_default_set
+ silence_warnings do # silence warnings raised by tzinfo gem
+ Time.zone_default = TimeZone['Eastern Time (US & Canada)']
+ with_env_tz 'US/Eastern' do
+ Time.stubs(:now).returns Time.local(2000)
+ assert_equal true, Time.current.is_a?(ActiveSupport::TimeWithZone)
+ assert_equal 'Eastern Time (US & Canada)', Time.current.time_zone.name
+ assert_equal Time.utc(2000), Time.current.time
+ end
+ end
+ ensure
+ Time.zone_default = nil
+ end
+ end
+
protected
def with_env_tz(new_tz = 'US/Eastern')
old_tz, ENV['TZ'] = ENV['TZ'], new_tz