1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Fix since and ago with a duration which has empty parts

Related #37839.

Sometimes divisions of `ActiveSupport::Duration` makes the instance's
parts attribute empty, but it has a value actually (e.g. `(1.minute /
60) # => @value=1 (second), but empty parts`).

In that case we should respect `value` as the source of seconds.
This commit is contained in:
Ryuta Kamizono 2019-12-02 17:58:00 +09:00
parent 23b738225f
commit aa93e3cb20
2 changed files with 10 additions and 4 deletions

View file

@ -403,8 +403,14 @@ module ActiveSupport
private
def sum(sign, time = ::Time.current)
parts.inject(time) do |t, (type, number)|
if t.acts_like?(:time) || t.acts_like?(:date)
unless time.acts_like?(:time) || time.acts_like?(:date)
raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
end
if parts.empty?
time.since(sign * value)
else
parts.inject(time) do |t, (type, number)|
if type == :seconds
t.since(sign * number)
elsif type == :minutes
@ -414,8 +420,6 @@ module ActiveSupport
else
t.advance(type => sign * number)
end
else
raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
end
end
end

View file

@ -204,7 +204,9 @@ class DurationTest < ActiveSupport::TestCase
def test_since_and_ago
t = Time.local(2000)
assert_equal t + 1, 1.second.since(t)
assert_equal t + 1, (1.minute / 60).since(t)
assert_equal t - 1, 1.second.ago(t)
assert_equal t - 1, (1.minute / 60).ago(t)
end
def test_since_and_ago_without_argument