From 887870f20c347179aef0545ee2019c02ed9f74d1 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sat, 15 Dec 2007 02:27:41 +0000 Subject: [PATCH] Ruby 1.9 compat: define Duration#== [chuyeow] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8399 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activesupport/lib/active_support/duration.rb | 60 +++++++++++-------- activesupport/test/core_ext/duration_test.rb | 1 - .../test/core_ext/numeric_ext_test.rb | 1 - 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/activesupport/lib/active_support/duration.rb b/activesupport/lib/active_support/duration.rb index fd9b505c2fa72..cbee4fd0ca7f5 100644 --- a/activesupport/lib/active_support/duration.rb +++ b/activesupport/lib/active_support/duration.rb @@ -6,11 +6,11 @@ module ActiveSupport # 1.month.ago # equivalent to Time.now.advance(:months => -1) class Duration < BasicObject attr_accessor :value, :parts - + def initialize(value, parts) #:nodoc: @value, @parts = value, parts end - + # Adds another Duration or a Numeric to this Duration. Numeric values # are treated as seconds. def +(other) @@ -20,39 +20,49 @@ def +(other) Duration.new(value + other, @parts + [[:seconds, other]]) end end - + # Subtracts another Duration or a Numeric from this Duration. Numeric # values are treated as seconds. def -(other) self + (-other) end - + def -@ #:nodoc: Duration.new(-value, parts.map { |type,number| [type, -number] }) end - + def is_a?(klass) #:nodoc: klass == Duration || super end - + + # Returns true if other is also a Duration instance with the + # same value, or if other == value. + def ==(other) + if Duration === other + other.value == value + else + other == value + end + end + def self.===(other) #:nodoc: other.is_a?(Duration) rescue super end - + # Calculates a new Time or Date that is as far in the future # as this Duration represents. def since(time = ::Time.now) 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) sum(-1, time) end alias :until :ago - + def inspect #:nodoc: consolidated = parts.inject(Hash.new(0)) { |h,part| h[part.first] += part.last; h } [:years, :months, :days, :minutes, :seconds].map do |length| @@ -60,27 +70,27 @@ def inspect #:nodoc: "#{n} #{n == 1 ? length.to_s.singularize : length.to_s}" if n.nonzero? end.compact.to_sentence end - + protected - - def sum(sign, time = ::Time.now) #:nodoc: - parts.inject(time) do |t,(type,number)| - if t.acts_like?(:time) || t.acts_like?(:date) - if type == :seconds - t.since(sign * number) + + def sum(sign, time = ::Time.now) #:nodoc: + parts.inject(time) do |t,(type,number)| + if t.acts_like?(:time) || t.acts_like?(:date) + if type == :seconds + t.since(sign * number) + else + t.advance(type => sign * number) + end else - t.advance(type => sign * number) + raise ArgumentError, "expected a time or date, got #{time.inspect}" end - else - raise ArgumentError, "expected a time or date, got #{time.inspect}" end end - end - + private - - def method_missing(method, *args, &block) #:nodoc: - value.send(method, *args) - end + + def method_missing(method, *args, &block) #:nodoc: + value.send(method, *args) + end end end diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb index 594252d58158d..125232bd4023c 100644 --- a/activesupport/test/core_ext/duration_test.rb +++ b/activesupport/test/core_ext/duration_test.rb @@ -15,7 +15,6 @@ def test_minus_with_duration_does_not_break_subtraction_of_date_from_date assert_nothing_raised { Date.today - Date.today } end - # FIXME: ruby 1.9 def test_plus_with_time assert_equal 1 + 1.second, 1.second + 1, "Duration + Numeric should == Numeric + Duration" end diff --git a/activesupport/test/core_ext/numeric_ext_test.rb b/activesupport/test/core_ext/numeric_ext_test.rb index 321f8165f4cdd..a773339b29b73 100644 --- a/activesupport/test/core_ext/numeric_ext_test.rb +++ b/activesupport/test/core_ext/numeric_ext_test.rb @@ -13,7 +13,6 @@ def setup } end - # FIXME: ruby 1.9 def test_units @seconds.each do |actual, expected| assert_equal expected, actual