aboutsummaryrefslogblamecommitdiffstats
path: root/activesupport/test/core_ext/duration_test.rb
blob: 9e97acaffb4c214e67dbbbc2178f540dbfeda8f1 (plain) (tree)
1
2
3
4
5
6
7
8
9
                       
                                  
                             
                             
                                
 
                                            

                             


                                           
                                             

                             






                                    





                                                       



                                                    




                              
                              


                            



                                   
              


                                                                               
                                  
                                    


                                


                                                 

     
                  
                                                                     




                                                                                         

                                                                                                   


                                                                       
 








                                                                                                  


                                                                           
 


                                                                                              

                         


                                     
                                                                                                                            
     
 
                           

                                              
     
 



                                      
 

                        

                                         








                                         
                                             
                        
           

                                                                    
         

                                                                


                                              
                        
           

                                                                         
         

                                                                     

     

                                                                       
                               







                                                                           
       
     
 

                                                                        
                               









                                                                                 
       
        
                   
     
 




                                                                                      
 




                                                                                   
 






                                      
 



                                       



                                         



                                               




                                   



                                               











                                              
   
require 'abstract_unit'
require 'active_support/inflector'
require 'active_support/time'
require 'active_support/json'
require 'time_zone_test_helpers'

class DurationTest < ActiveSupport::TestCase
  include TimeZoneTestHelpers

  def test_is_a
    d = 1.day
    assert d.is_a?(ActiveSupport::Duration)
    assert_kind_of ActiveSupport::Duration, d
    assert_kind_of Numeric, d
    assert_kind_of Fixnum, d
    assert !d.is_a?(Hash)

    k = Class.new
    class << k; undef_method :== end
    assert !d.is_a?(k)
  end

  def test_instance_of
    assert 1.minute.instance_of?(Fixnum)
    assert 2.days.instance_of?(ActiveSupport::Duration)
    assert !3.second.instance_of?(Numeric)
  end

  def test_threequals
    assert ActiveSupport::Duration === 1.day
    assert !(ActiveSupport::Duration === 1.day.to_i)
    assert !(ActiveSupport::Duration === 'foo')
  end

  def test_equals
    assert 1.day == 1.day
    assert 1.day == 1.day.to_i
    assert 1.day.to_i == 1.day
    assert !(1.day == 'foo')
  end

  def test_to_s
    assert_equal "1", 1.second.to_s
  end

  def test_eql
    rubinius_skip "Rubinius' #eql? definition relies on #instance_of? " \
                  "which behaves oddly for the sake of backward-compatibility."

    assert 1.minute.eql?(1.minute)
    assert 1.minute.eql?(60.seconds)
    assert 2.days.eql?(48.hours)
    assert !1.second.eql?(1)
    assert !1.eql?(1.second)
    assert 1.minute.eql?(180.seconds - 2.minutes)
    assert !1.minute.eql?(60)
    assert !1.minute.eql?('foo')
  end

  def test_inspect
    assert_equal '0 seconds',                       0.seconds.inspect
    assert_equal '1 month',                         1.month.inspect
    assert_equal '1 month and 1 day',               (1.month + 1.day).inspect
    assert_equal '6 months and -2 days',            (6.months - 2.days).inspect
    assert_equal '10 seconds',                      10.seconds.inspect
    assert_equal '10 years, 2 months, and 1 day',   (10.years + 2.months + 1.day).inspect
    assert_equal '10 years, 2 months, and 1 day',   (10.years + 1.month  + 1.day + 1.month).inspect
    assert_equal '10 years, 2 months, and 1 day',   (1.day + 10.years + 2.months).inspect
    assert_equal '7 days',                          1.week.inspect
    assert_equal '14 days',                         1.fortnight.inspect
  end

  def test_inspect_locale
    current_locale = I18n.default_locale
    I18n.default_locale = :de
    I18n.backend.store_translations(:de, { support: { array: { last_word_connector: ' und ' } } })
    assert_equal '10 years, 1 month und 1 day', (10.years + 1.month  + 1.day).inspect
  ensure
    I18n.default_locale = current_locale
  end

  def test_minus_with_duration_does_not_break_subtraction_of_date_from_date
    assert_nothing_raised { Date.today - Date.today }
  end

  def test_plus_with_time
    assert_equal 1 + 1.second, 1.second + 1, "Duration + Numeric should == Numeric + Duration"
  end

  def test_argument_error
    e = assert_raise ArgumentError do
      1.second.ago('')
    end
    assert_equal 'expected a time or date, got ""', e.message, "ensure ArgumentError is not being raised by dependencies.rb"
  end

  def test_fractional_weeks
    assert_equal((86400 * 7) * 1.5, 1.5.weeks)
    assert_equal((86400 * 7) * 1.7, 1.7.weeks)
  end

  def test_fractional_days
    assert_equal 86400 * 1.5, 1.5.days
    assert_equal 86400 * 1.7, 1.7.days
  end

  def test_since_and_ago
    t = Time.local(2000)
    assert_equal t + 1, 1.second.since(t)
    assert_equal t - 1, 1.second.ago(t)
  end

  def test_since_and_ago_without_argument
    now = Time.now
    assert 1.second.since >= now + 1
    now = Time.now
    assert 1.second.ago >= now - 1
  end

  def test_since_and_ago_with_fractional_days
    t = Time.local(2000)
    # since
    assert_equal 36.hours.since(t), 1.5.days.since(t)
    assert_in_delta((24 * 1.7).hours.since(t), 1.7.days.since(t), 1)
    # ago
    assert_equal 36.hours.ago(t), 1.5.days.ago(t)
    assert_in_delta((24 * 1.7).hours.ago(t), 1.7.days.ago(t), 1)
  end

  def test_since_and_ago_with_fractional_weeks
    t = Time.local(2000)
    # since
    assert_equal((7 * 36).hours.since(t), 1.5.weeks.since(t))
    assert_in_delta((7 * 24 * 1.7).hours.since(t), 1.7.weeks.since(t), 1)
    # ago
    assert_equal((7 * 36).hours.ago(t), 1.5.weeks.ago(t))
    assert_in_delta((7 * 24 * 1.7).hours.ago(t), 1.7.weeks.ago(t), 1)
  end

  def test_since_and_ago_anchored_to_time_now_when_time_zone_is_not_set
    Time.zone = nil
    with_env_tz 'US/Eastern' do
      Time.stub(:now, Time.local(2000)) do
        # since
        assert_not_instance_of ActiveSupport::TimeWithZone, 5.seconds.since
        assert_equal Time.local(2000,1,1,0,0,5), 5.seconds.since
        # ago
        assert_not_instance_of ActiveSupport::TimeWithZone, 5.seconds.ago
        assert_equal Time.local(1999,12,31,23,59,55), 5.seconds.ago
      end
    end
  end

  def test_since_and_ago_anchored_to_time_zone_now_when_time_zone_is_set
    Time.zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
    with_env_tz 'US/Eastern' do
      Time.stub(:now, Time.local(2000)) do
        # since
        assert_instance_of ActiveSupport::TimeWithZone, 5.seconds.since
        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_instance_of ActiveSupport::TimeWithZone, 5.seconds.ago
        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 = nil
  end

  def test_adding_hours_across_dst_boundary
    with_env_tz 'CET' do
      assert_equal Time.local(2009,3,29,0,0,0) + 24.hours, Time.local(2009,3,30,1,0,0)
    end
  end

  def test_adding_day_across_dst_boundary
    with_env_tz 'CET' do
      assert_equal Time.local(2009,3,29,0,0,0) + 1.day, Time.local(2009,3,30,0,0,0)
    end
  end

  def test_delegation_with_block_works
    counter = 0
    assert_nothing_raised do
      1.minute.times {counter += 1}
    end
    assert_equal counter, 60
  end

  def test_as_json
    assert_equal 172800, 2.days.as_json
  end

  def test_to_json
    assert_equal '172800', 2.days.to_json
  end

  def test_case_when
    cased = case 1.day when 1.day then "ok" end
    assert_equal cased, "ok"
  end

  def test_respond_to
    assert_respond_to 1.day, :since
    assert_respond_to 1.day, :zero?
  end

  def test_hash
    assert_equal 1.minute.hash, 60.seconds.hash
  end

  def test_comparable
    assert_equal(-1, (0.seconds <=> 1.second))
    assert_equal(-1, (1.second <=> 1.minute))
    assert_equal(-1, (1 <=> 1.minute))
    assert_equal(0, (0.seconds <=> 0.seconds))
    assert_equal(0, (0.seconds <=> 0.minutes))
    assert_equal(0, (1.second <=> 1.second))
    assert_equal(1, (1.second <=> 0.second))
    assert_equal(1, (1.minute <=> 1.second))
    assert_equal(1, (61 <=> 1.minute))
  end
end