From e5e1d7ea50ea225aca4693f8047530b9bbb9b438 Mon Sep 17 00:00:00 2001 From: Clemens Kofler Date: Sun, 13 Mar 2011 22:23:18 +0100 Subject: [PATCH] distance_of_time_in_words and time_ago_in_words should use include_seconds as part of the options hash --- actionpack/lib/action_view/helpers/date_helper.rb | 63 +++++++++++++------- actionpack/test/template/date_helper_i18n_test.rb | 47 +++++++++------- actionpack/test/template/date_helper_test.rb | 33 ++++++----- 3 files changed, 86 insertions(+), 57 deletions(-) diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 6cd1565..4321a0e 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -19,7 +19,13 @@ module ActionView # "date[month]". module DateHelper # Reports the approximate distance in time between two Time or Date objects or integers as seconds. - # Set include_seconds to true if you want more detailed approximations when distance < 1 min, 29 secs + # + # You can customize the format in the +options+ hash. + # + # ==== Options + # * :locale - Sets the locale to be used for formatting (defaults to current locale). + # * :include_seconds - Set to true if you want more detailed approximations when distance < 1 minute 29 seconds (defaults to false). + # # Distances are reported based on the following table: # # 0 <-> 29 secs # => less than a minute @@ -46,30 +52,42 @@ module ActionView # # ==== Examples # from_time = Time.now - # distance_of_time_in_words(from_time, from_time + 50.minutes) # => about 1 hour - # distance_of_time_in_words(from_time, 50.minutes.from_now) # => about 1 hour - # distance_of_time_in_words(from_time, from_time + 15.seconds) # => less than a minute - # distance_of_time_in_words(from_time, from_time + 15.seconds, true) # => less than 20 seconds - # distance_of_time_in_words(from_time, 3.years.from_now) # => about 3 years - # distance_of_time_in_words(from_time, from_time + 60.hours) # => about 3 days - # distance_of_time_in_words(from_time, from_time + 45.seconds, true) # => less than a minute - # distance_of_time_in_words(from_time, from_time - 45.seconds, true) # => less than a minute - # distance_of_time_in_words(from_time, 76.seconds.from_now) # => 1 minute - # distance_of_time_in_words(from_time, from_time + 1.year + 3.days) # => about 1 year - # distance_of_time_in_words(from_time, from_time + 3.years + 6.months) # => over 3 years + # distance_of_time_in_words(from_time, from_time + 15.seconds) # => less than a minute + # distance_of_time_in_words(from_time, from_time + 50.minutes) # => about 1 hour + # distance_of_time_in_words(from_time, 50.minutes.from_now) # => about 1 hour + # distance_of_time_in_words(from_time, 3.years.from_now) # => about 3 years + # distance_of_time_in_words(from_time, from_time + 60.hours) # => about 3 days + # distance_of_time_in_words(from_time, 76.seconds.from_now) # => 1 minute + # distance_of_time_in_words(from_time, from_time + 1.year + 3.days) # => about 1 year + # distance_of_time_in_words(from_time, from_time + 3.years + 6.months) # => over 3 years # distance_of_time_in_words(from_time, from_time + 4.years + 9.days + 30.minutes + 5.seconds) # => about 4 years # + # distance_of_time_in_words(from_time, from_time + 15.seconds, :include_seconds => true) # => less than 20 seconds + # distance_of_time_in_words(from_time, from_time + 45.seconds, :include_seconds => true) # => less than a minute + # distance_of_time_in_words(from_time, from_time - 45.seconds, :include_seconds => true) # => less than a minute + # # to_time = Time.now + 6.years + 19.days - # distance_of_time_in_words(from_time, to_time, true) # => about 6 years - # distance_of_time_in_words(to_time, from_time, true) # => about 6 years - # distance_of_time_in_words(Time.now, Time.now) # => less than a minute + # distance_of_time_in_words(from_time, to_time) # => about 6 years + # distance_of_time_in_words(to_time, from_time) # => about 6 years + # distance_of_time_in_words(Time.now, Time.now) # => less than a minute # - def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false, options = {}) + def distance_of_time_in_words(from_time, to_time = 0, *args) + options = args.extract_options! + options.symbolize_keys! + from_time = from_time.to_time if from_time.respond_to?(:to_time) to_time = to_time.to_time if to_time.respond_to?(:to_time) distance_in_minutes = (((to_time - from_time).abs)/60).round distance_in_seconds = ((to_time - from_time).abs).round + include_seconds = options[:include_seconds] + + unless args.empty? + ActiveSupport::Deprecation.warn('distance_of_time_in_words now takes :include_seconds ' + + 'as part of the options hash instead of a fixed argument.', caller) + include_seconds = args[0] + end + I18n.with_options :locale => options[:locale], :scope => :'datetime.distance_in_words' do |locale| case distance_in_minutes when 0..1 @@ -111,13 +129,14 @@ module ActionView # Like distance_of_time_in_words, but where to_time is fixed to Time.now. # # ==== Examples - # time_ago_in_words(3.minutes.from_now) # => 3 minutes - # time_ago_in_words(Time.now - 15.hours) # => 15 hours - # time_ago_in_words(Time.now) # => less than a minute - # - # from_time = Time.now - 3.days - 14.minutes - 25.seconds # => 3 days - def time_ago_in_words(from_time, include_seconds = false) - distance_of_time_in_words(from_time, Time.now, include_seconds) + # time_ago_in_words(3.minutes.from_now) # => 3 minutes + # time_ago_in_words(Time.now - 15.hours) # => 15 hours + # time_ago_in_words(Time.now) # => less than a minute + # time_ago_in_words(7.seconds.ago, :include_seconds => true) # => less than 10 seconds + # + # from_time = Time.now - 3.days - 14.minutes - 25.seconds # => 3 days + def time_ago_in_words(from_time, options = {}) + distance_of_time_in_words(from_time, Time.now, options) end alias_method :distance_of_time_in_words_to_now, :time_ago_in_words diff --git a/actionpack/test/template/date_helper_i18n_test.rb b/actionpack/test/template/date_helper_i18n_test.rb index d45215a..ba338d9 100644 --- a/actionpack/test/template/date_helper_i18n_test.rb +++ b/actionpack/test/template/date_helper_i18n_test.rb @@ -12,24 +12,24 @@ class DateHelperDistanceOfTimeInWordsI18nTests < Test::Unit::TestCase def test_distance_of_time_in_words_calls_i18n { # with include_seconds - [2.seconds, true] => [:'less_than_x_seconds', 5], - [9.seconds, true] => [:'less_than_x_seconds', 10], - [19.seconds, true] => [:'less_than_x_seconds', 20], - [30.seconds, true] => [:'half_a_minute', nil], - [59.seconds, true] => [:'less_than_x_minutes', 1], - [60.seconds, true] => [:'x_minutes', 1], + [2.seconds, { :include_seconds => true }] => [:'less_than_x_seconds', 5], + [9.seconds, { :include_seconds => true }] => [:'less_than_x_seconds', 10], + [19.seconds, { :include_seconds => true }] => [:'less_than_x_seconds', 20], + [30.seconds, { :include_seconds => true }] => [:'half_a_minute', nil], + [59.seconds, { :include_seconds => true }] => [:'less_than_x_minutes', 1], + [60.seconds, { :include_seconds => true }] => [:'x_minutes', 1], # without include_seconds - [29.seconds, false] => [:'less_than_x_minutes', 1], - [60.seconds, false] => [:'x_minutes', 1], - [44.minutes, false] => [:'x_minutes', 44], - [61.minutes, false] => [:'about_x_hours', 1], - [24.hours, false] => [:'x_days', 1], - [30.days, false] => [:'about_x_months', 1], - [60.days, false] => [:'x_months', 2], - [1.year, false] => [:'about_x_years', 1], - [3.years + 6.months, false] => [:'over_x_years', 3], - [3.years + 10.months, false] => [:'almost_x_years', 4] + [29.seconds, { :include_seconds => false }] => [:'less_than_x_minutes', 1], + [60.seconds, { :include_seconds => false }] => [:'x_minutes', 1], + [44.minutes, { :include_seconds => false }] => [:'x_minutes', 44], + [61.minutes, { :include_seconds => false }] => [:'about_x_hours', 1], + [24.hours, { :include_seconds => false }] => [:'x_days', 1], + [30.days, { :include_seconds => false }] => [:'about_x_months', 1], + [60.days, { :include_seconds => false }] => [:'x_months', 2], + [1.year, { :include_seconds => false }] => [:'about_x_years', 1], + [3.years + 6.months, { :include_seconds => false }] => [:'over_x_years', 3], + [3.years + 10.months, { :include_seconds => false }] => [:'almost_x_years', 4] }.each do |passed, expected| assert_distance_of_time_in_words_translates_key passed, expected @@ -37,15 +37,20 @@ class DateHelperDistanceOfTimeInWordsI18nTests < Test::Unit::TestCase end def assert_distance_of_time_in_words_translates_key(passed, expected) - diff, include_seconds = *passed + diff, options = *passed key, count = *expected to = @from + diff - options = {:locale => 'en', :scope => :'datetime.distance_in_words'} - options[:count] = count if count + t_options = {:locale => 'en', :scope => :'datetime.distance_in_words'} + t_options[:count] = count if count - I18n.expects(:t).with(key, options) - distance_of_time_in_words(@from, to, include_seconds, :locale => 'en') + I18n.expects(:t).with(key, t_options) + distance_of_time_in_words(@from, to, options.merge(:locale => 'en')) + end + + def test_time_ago_in_words + I18n.expects(:t).with(:less_than_x_seconds, :count => 10, :locale => 'en', :scope => :'datetime.distance_in_words') + time_ago_in_words(7.seconds.ago, :include_seconds => true, :locale => 'en') end def test_distance_of_time_pluralizations diff --git a/actionpack/test/template/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb index aca2fef..94f2b6e 100644 --- a/actionpack/test/template/date_helper_test.rb +++ b/actionpack/test/template/date_helper_test.rb @@ -21,19 +21,20 @@ class DateHelperTest < ActionView::TestCase def assert_distance_of_time_in_words(from, to=nil) to ||= from - # 0..1 with include_seconds - assert_equal "less than 5 seconds", distance_of_time_in_words(from, to + 0.seconds, true) - assert_equal "less than 5 seconds", distance_of_time_in_words(from, to + 4.seconds, true) - assert_equal "less than 10 seconds", distance_of_time_in_words(from, to + 5.seconds, true) - assert_equal "less than 10 seconds", distance_of_time_in_words(from, to + 9.seconds, true) - assert_equal "less than 20 seconds", distance_of_time_in_words(from, to + 10.seconds, true) - assert_equal "less than 20 seconds", distance_of_time_in_words(from, to + 19.seconds, true) - assert_equal "half a minute", distance_of_time_in_words(from, to + 20.seconds, true) - assert_equal "half a minute", distance_of_time_in_words(from, to + 39.seconds, true) - assert_equal "less than a minute", distance_of_time_in_words(from, to + 40.seconds, true) - assert_equal "less than a minute", distance_of_time_in_words(from, to + 59.seconds, true) - assert_equal "1 minute", distance_of_time_in_words(from, to + 60.seconds, true) - assert_equal "1 minute", distance_of_time_in_words(from, to + 89.seconds, true) + # 0..1 with :include_seconds => true + options = { :include_seconds => true } + assert_equal "less than 5 seconds", distance_of_time_in_words(from, to + 0.seconds, options) + assert_equal "less than 5 seconds", distance_of_time_in_words(from, to + 4.seconds, options) + assert_equal "less than 10 seconds", distance_of_time_in_words(from, to + 5.seconds, options) + assert_equal "less than 10 seconds", distance_of_time_in_words(from, to + 9.seconds, options) + assert_equal "less than 20 seconds", distance_of_time_in_words(from, to + 10.seconds, options) + assert_equal "less than 20 seconds", distance_of_time_in_words(from, to + 19.seconds, options) + assert_equal "half a minute", distance_of_time_in_words(from, to + 20.seconds, options) + assert_equal "half a minute", distance_of_time_in_words(from, to + 39.seconds, options) + assert_equal "less than a minute", distance_of_time_in_words(from, to + 40.seconds, options) + assert_equal "less than a minute", distance_of_time_in_words(from, to + 59.seconds, options) + assert_equal "1 minute", distance_of_time_in_words(from, to + 60.seconds, options) + assert_equal "1 minute", distance_of_time_in_words(from, to + 89.seconds, options) # First case 0..1 assert_equal "less than a minute", distance_of_time_in_words(from, to + 0.seconds) @@ -95,7 +96,7 @@ class DateHelperTest < ActionView::TestCase # test to < from assert_equal "about 4 hours", distance_of_time_in_words(from + 4.hours, to) - assert_equal "less than 20 seconds", distance_of_time_in_words(from + 19.seconds, to, true) + assert_equal "less than 20 seconds", distance_of_time_in_words(from + 19.seconds, to, :include_seconds => true) end def test_distance_in_words @@ -134,6 +135,10 @@ class DateHelperTest < ActionView::TestCase assert_equal "about 1 year", time_ago_in_words(1.year.ago - 1.day) end + def test_time_ago_in_words_with_include_seconds + assert_equal "less than 10 seconds", time_ago_in_words(7.seconds.ago, :include_seconds => true) + end + def test_select_day expected = %(