working_hours 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +5 -0
- data/CHANGELOG.md +3 -0
- data/README.md +19 -4
- data/gemfiles/Gemfile.activesupport-4.2.x +5 -0
- data/lib/working_hours/computation.rb +3 -3
- data/lib/working_hours/config.rb +27 -4
- data/lib/working_hours/core_ext/date_and_time.rb +1 -5
- data/lib/working_hours/version.rb +1 -1
- data/spec/spec_helper.rb +0 -1
- data/spec/working_hours/computation_spec.rb +13 -0
- data/spec/working_hours/config_spec.rb +100 -3
- data/spec/working_hours/core_ext/date_and_time_spec.rb +40 -2
- data/working_hours.gemspec +1 -1
- metadata +6 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 1b22e4d023c26a46743000425945952ab1bab9fd
         | 
| 4 | 
            +
              data.tar.gz: cbed8ec547a77301003e9dc7ed0686c08f2cac46
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: a63290c01a8c6f78782a7abc917b655e16d97c115f44c1c3a075cfe067ddc8a68a4df7fc609d10ba81beb471e963032b7491df872b0ea372e8585377832b938b
         | 
| 7 | 
            +
              data.tar.gz: a65bebd4a98cd33caccd717924166bbc89057f7b0800385cca6902ef2a76a1d5367cda365de1926000f37816f028fbb728154db5ae1d9ac08fe43050e279152f
         | 
    
        data/.travis.yml
    CHANGED
    
    | @@ -3,12 +3,17 @@ rvm: | |
| 3 3 | 
             
              - 2.0.0
         | 
| 4 4 | 
             
              - 2.1.3
         | 
| 5 5 | 
             
              - ruby-head
         | 
| 6 | 
            +
              - jruby-1.7.19
         | 
| 6 7 | 
             
              - jruby-head
         | 
| 8 | 
            +
            env: JRUBY_OPTS=--2.0
         | 
| 7 9 | 
             
            gemfile:
         | 
| 8 10 | 
             
              - gemfiles/Gemfile.activesupport-3.2.x
         | 
| 9 11 | 
             
              - gemfiles/Gemfile.activesupport-4.0.x
         | 
| 10 12 | 
             
              - gemfiles/Gemfile.activesupport-4.1.x
         | 
| 13 | 
            +
              - gemfiles/Gemfile.activesupport-4.2.x
         | 
| 11 14 | 
             
              - gemfiles/Gemfile.activesupport-edge
         | 
| 12 15 | 
             
            matrix:
         | 
| 13 16 | 
             
              allow_failures:
         | 
| 14 17 | 
             
                - gemfile: gemfiles/Gemfile.activesupport-edge
         | 
| 18 | 
            +
                - rvm: ruby-head
         | 
| 19 | 
            +
                - rvm: jruby-head
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -2,6 +2,9 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            [Compare master with v1.0.3](https://github.com/intrepidd/working_hours/compare/v1.0.3...master)
         | 
| 4 4 |  | 
| 5 | 
            +
            # v1.0.4
         | 
| 6 | 
            +
            * Fixed a nasty stack level too deep error on DateTime#+ and DateTime#- (thanks @jlanatta)
         | 
| 7 | 
            +
             | 
| 5 8 | 
             
            # v1.0.3
         | 
| 6 9 |  | 
| 7 10 | 
             
            * Relax configuration input formats - [#10](https://github.com/Intrepidd/working_hours/pull/10)
         | 
    
        data/README.md
    CHANGED
    
    | @@ -71,8 +71,8 @@ WorkingHours::Config.working_hours = { | |
| 71 71 | 
             
              :tue => {'09:00' => '12:00', '13:00' => '17:00'},
         | 
| 72 72 | 
             
              :wed => {'09:00' => '12:00', '13:00' => '17:00'},
         | 
| 73 73 | 
             
              :thu => {'09:00' => '12:00', '13:00' => '17:00'},
         | 
| 74 | 
            -
              :fri => {'09:00' => '12:00', '13:00' => '17: | 
| 75 | 
            -
              :sat => {' | 
| 74 | 
            +
              :fri => {'09:00' => '12:00', '13:00' => '17:05:30'},
         | 
| 75 | 
            +
              :sat => {'19:00' => '24:00'}
         | 
| 76 76 | 
             
            }
         | 
| 77 77 |  | 
| 78 78 | 
             
            # Configure timezone (uses activesupport, defaults to UTC)
         | 
| @@ -82,6 +82,19 @@ WorkingHours::Config.time_zone = 'Paris' | |
| 82 82 | 
             
            WorkingHours::Config.holidays = [Date.new(2014, 12, 31)]
         | 
| 83 83 | 
             
            ```
         | 
| 84 84 |  | 
| 85 | 
            +
            Alternatively, you can apply a particular config in a block with the ``with_config`` method :
         | 
| 86 | 
            +
             | 
| 87 | 
            +
            ```ruby
         | 
| 88 | 
            +
            WorkingHours::Config.with_config(working_hours: {mon:{'09:00' => '18:00'}}, holidays: [], time_zone: 'Paris') do
         | 
| 89 | 
            +
              # Intense calculations
         | 
| 90 | 
            +
            end
         | 
| 91 | 
            +
            ```
         | 
| 92 | 
            +
            ``with_config`` uses keyword arguments, you can pass all or some of the supported arguments :
         | 
| 93 | 
            +
            - ``working_hours``
         | 
| 94 | 
            +
            - ``holidays``
         | 
| 95 | 
            +
            - ``time_zone``
         | 
| 96 | 
            +
             | 
| 97 | 
            +
             | 
| 85 98 | 
             
            ## No core extensions / monkey patching
         | 
| 86 99 |  | 
| 87 100 | 
             
            Core extensions (monkey patching to add methods on Time, Date, Numbers, etc.) are handy but not appreciated by everyone. WorkingHours can also be used **without any monkey patching**:
         | 
| @@ -133,7 +146,7 @@ require 'working_hours/module' | |
| 133 146 | 
             
            class Order
         | 
| 134 147 | 
             
              include WorkingHours
         | 
| 135 148 |  | 
| 136 | 
            -
              def  | 
| 149 | 
            +
              def shipping_date_estimate
         | 
| 137 150 | 
             
                Duration.new(2, :days).since(payment_received_at)
         | 
| 138 151 | 
             
              end
         | 
| 139 152 |  | 
| @@ -145,12 +158,14 @@ end | |
| 145 158 |  | 
| 146 159 | 
             
            ## Timezones
         | 
| 147 160 |  | 
| 148 | 
            -
            This gem uses a simple but efficient approach in dealing with timezones. When you define your working hours **you have to choose** a timezone associated with it (in the config example, the working hours are in Paris time). Then, any time used in  | 
| 161 | 
            +
            This gem uses a simple but efficient approach in dealing with timezones. When you define your working hours **you have to choose** a timezone associated with it (in the config example, the working hours are in Paris time). Then, any time used in calculation will be converted to this timezone first, so you don't have to worry if your times are local or UTC as long as they are correct :)
         | 
| 149 162 |  | 
| 150 163 | 
             
            ## Alternatives
         | 
| 151 164 |  | 
| 152 165 | 
             
            There is a gem called [business_time](https://github.com/bokmann/business_time) already available to do this kind of computation and it was of great help to us. But we decided to start another one because business_time is suffering from a few [bugs](https://github.com/bokmann/business_time/pull/84) and [inconsistencies](https://github.com/bokmann/business_time/issues/50). It also lacks essential features to us (like working minutes computation).
         | 
| 153 166 |  | 
| 167 | 
            +
            Another gem called [biz](https://github.com/zendesk/biz) was released after working_hours to bring some alternative.
         | 
| 168 | 
            +
             | 
| 154 169 | 
             
            ## Contributing
         | 
| 155 170 |  | 
| 156 171 | 
             
            1. Fork it ( http://github.com/intrepidd/working_hours/fork )
         | 
| @@ -39,7 +39,7 @@ module WorkingHours | |
| 39 39 | 
             
                    config[:working_hours][time.wday].each do |from, to|
         | 
| 40 40 | 
             
                      if time_in_day >= from and time_in_day < to
         | 
| 41 41 | 
             
                        # take all we can
         | 
| 42 | 
            -
                        take = [to - time_in_day, seconds].min
         | 
| 42 | 
            +
                        take = [to - time_in_day, seconds].min.round
         | 
| 43 43 | 
             
                        # advance time
         | 
| 44 44 | 
             
                        time += take
         | 
| 45 45 | 
             
                        # decrease seconds
         | 
| @@ -55,7 +55,7 @@ module WorkingHours | |
| 55 55 | 
             
                    config[:working_hours][time.wday].reverse_each do |from, to|
         | 
| 56 56 | 
             
                      if time_in_day > from and time_in_day <= to
         | 
| 57 57 | 
             
                        # take all we can
         | 
| 58 | 
            -
                        take = [time_in_day - from, -seconds].min
         | 
| 58 | 
            +
                        take = [time_in_day - from, -seconds].min.round
         | 
| 59 59 | 
             
                        # advance time
         | 
| 60 60 | 
             
                        time -= take
         | 
| 61 61 | 
             
                        # decrease seconds
         | 
| @@ -162,7 +162,7 @@ module WorkingHours | |
| 162 162 | 
             
                      # roll to next business period
         | 
| 163 163 | 
             
                      from = advance_to_working_time(from, config: config)
         | 
| 164 164 | 
             
                    end
         | 
| 165 | 
            -
                    distance
         | 
| 165 | 
            +
                    distance.round # round up to supress miliseconds introduced by 24:00 hack
         | 
| 166 166 | 
             
                  end
         | 
| 167 167 | 
             
                end
         | 
| 168 168 |  | 
    
        data/lib/working_hours/config.rb
    CHANGED
    
    | @@ -5,7 +5,7 @@ module WorkingHours | |
| 5 5 |  | 
| 6 6 | 
             
              class Config
         | 
| 7 7 |  | 
| 8 | 
            -
                TIME_FORMAT = /\A([0- | 
| 8 | 
            +
                TIME_FORMAT = /\A([0-2][0-9])\:([0-5][0-9])(?:\:([0-5][0-9]))?\z/
         | 
| 9 9 | 
             
                DAYS_OF_WEEK = [:sun, :mon, :tue, :wed, :thu, :fri, :sat]
         | 
| 10 10 |  | 
| 11 11 | 
             
                class << self
         | 
| @@ -39,6 +39,9 @@ module WorkingHours | |
| 39 39 | 
             
                    end
         | 
| 40 40 |  | 
| 41 41 | 
             
                    config[:precompiled] ||= begin
         | 
| 42 | 
            +
                      validate_working_hours! config[:working_hours]
         | 
| 43 | 
            +
                      validate_holidays! config[:holidays]
         | 
| 44 | 
            +
                      validate_time_zone! config[:time_zone]
         | 
| 42 45 | 
             
                      compiled = {working_hours: []}
         | 
| 43 46 | 
             
                      working_hours.each do |day, hours|
         | 
| 44 47 | 
             
                        compiled[:working_hours][DAYS_OF_WEEK.index(day)] = {}
         | 
| @@ -66,6 +69,20 @@ module WorkingHours | |
| 66 69 | 
             
                    Thread.current[:working_hours] = default_config
         | 
| 67 70 | 
             
                  end
         | 
| 68 71 |  | 
| 72 | 
            +
                  def with_config(working_hours: nil, holidays: nil, time_zone: nil)
         | 
| 73 | 
            +
                    original_working_hours = self.working_hours
         | 
| 74 | 
            +
                    original_holidays = self.holidays
         | 
| 75 | 
            +
                    original_time_zone = self.time_zone
         | 
| 76 | 
            +
                    self.working_hours = working_hours if working_hours
         | 
| 77 | 
            +
                    self.holidays = holidays if holidays
         | 
| 78 | 
            +
                    self.time_zone = time_zone if time_zone
         | 
| 79 | 
            +
                    yield
         | 
| 80 | 
            +
                  ensure
         | 
| 81 | 
            +
                    self.working_hours = original_working_hours
         | 
| 82 | 
            +
                    self.holidays = original_holidays
         | 
| 83 | 
            +
                    self.time_zone = original_time_zone
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
             | 
| 69 86 | 
             
                  private
         | 
| 70 87 |  | 
| 71 88 | 
             
                  def config
         | 
| @@ -89,7 +106,11 @@ module WorkingHours | |
| 89 106 | 
             
                  def compile_time time
         | 
| 90 107 | 
             
                    hour = time[TIME_FORMAT,1].to_i
         | 
| 91 108 | 
             
                    min = time[TIME_FORMAT,2].to_i
         | 
| 92 | 
            -
                     | 
| 109 | 
            +
                    sec = time[TIME_FORMAT,3].to_i
         | 
| 110 | 
            +
                    time = hour * 3600 + min * 60 + sec
         | 
| 111 | 
            +
                    # Converts 24:00 to 23:59:59.999999
         | 
| 112 | 
            +
                    return 86399.999999 if time == 86400
         | 
| 113 | 
            +
                    time
         | 
| 93 114 | 
             
                  end
         | 
| 94 115 |  | 
| 95 116 | 
             
                  def validate_working_hours! week
         | 
| @@ -108,9 +129,11 @@ module WorkingHours | |
| 108 129 | 
             
                      last_time = nil
         | 
| 109 130 | 
             
                      hours.sort.each do |start, finish|
         | 
| 110 131 | 
             
                        if not start =~ TIME_FORMAT
         | 
| 111 | 
            -
                          raise InvalidConfiguration.new "Invalid time: #{start} - must be 'HH:MM'"
         | 
| 132 | 
            +
                          raise InvalidConfiguration.new "Invalid time: #{start} - must be 'HH:MM(:SS)'"
         | 
| 112 133 | 
             
                        elsif not finish =~ TIME_FORMAT
         | 
| 113 | 
            -
                          raise InvalidConfiguration.new "Invalid time: #{finish} - must be 'HH:MM'"
         | 
| 134 | 
            +
                          raise InvalidConfiguration.new "Invalid time: #{finish} - must be 'HH:MM(:SS)'"
         | 
| 135 | 
            +
                        elsif compile_time(finish) >= 24 * 60 * 60
         | 
| 136 | 
            +
                          raise InvalidConfiguration.new "Invalid time: #{finish} - outside of day"
         | 
| 114 137 | 
             
                        elsif start >= finish
         | 
| 115 138 | 
             
                          raise InvalidConfiguration.new "Invalid range: #{start} => #{finish} - ends before it starts"
         | 
| 116 139 | 
             
                        elsif last_time and start < last_time
         | 
| @@ -53,14 +53,10 @@ class Date | |
| 53 53 | 
             
              include WorkingHours::CoreExt::DateAndTime
         | 
| 54 54 | 
             
            end
         | 
| 55 55 |  | 
| 56 | 
            -
            class DateTime
         | 
| 57 | 
            -
              include WorkingHours::CoreExt::DateAndTime
         | 
| 58 | 
            -
            end
         | 
| 59 | 
            -
             | 
| 60 56 | 
             
            class Time
         | 
| 61 57 | 
             
              include WorkingHours::CoreExt::DateAndTime
         | 
| 62 58 | 
             
            end
         | 
| 63 59 |  | 
| 64 60 | 
             
            class ActiveSupport::TimeWithZone
         | 
| 65 61 | 
             
              include WorkingHours::CoreExt::DateAndTime
         | 
| 66 | 
            -
            end
         | 
| 62 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -10,7 +10,6 @@ require 'timecop' | |
| 10 10 |  | 
| 11 11 | 
             
            RSpec.configure do |config|
         | 
| 12 12 | 
             
              config.run_all_when_everything_filtered = true
         | 
| 13 | 
            -
              config.filter_run :focus
         | 
| 14 13 |  | 
| 15 14 | 
             
              # Run specs in random order to surface order dependencies. If you find an
         | 
| 16 15 | 
             
              # order dependency and want to debug it, you can fix the order by providing
         | 
| @@ -98,6 +98,11 @@ describe WorkingHours::Computation do | |
| 98 98 | 
             
                  add_seconds(time, 120)
         | 
| 99 99 | 
             
                end
         | 
| 100 100 |  | 
| 101 | 
            +
                it 'supports midnight' do
         | 
| 102 | 
            +
                  WorkingHours::Config.working_hours = {:mon => {'00:00' => '24:00'}}
         | 
| 103 | 
            +
                  time = Time.utc(2014, 4, 7, 23, 59, 30) # Friday
         | 
| 104 | 
            +
                  expect(add_seconds(time, 60)).to eq(Time.utc(2014, 4, 14, 0, 0, 30))
         | 
| 105 | 
            +
                end
         | 
| 101 106 | 
             
              end
         | 
| 102 107 |  | 
| 103 108 | 
             
              describe '#advance_to_working_time' do
         | 
| @@ -310,6 +315,14 @@ describe WorkingHours::Computation do | |
| 310 315 | 
             
                  )).to eq(8.hours)
         | 
| 311 316 | 
             
                end
         | 
| 312 317 |  | 
| 318 | 
            +
                it 'supports midnight' do
         | 
| 319 | 
            +
                  WorkingHours::Config.working_hours = {:mon => {'00:00' => '24:00'}}
         | 
| 320 | 
            +
                  expect(working_time_between(
         | 
| 321 | 
            +
                    Time.utc(2014, 4, 6, 12),
         | 
| 322 | 
            +
                    Time.utc(2016, 4, 6, 12)
         | 
| 323 | 
            +
                  )).to eq(24.hours * 105) # 105 complete mondays in 2 years
         | 
| 324 | 
            +
                end
         | 
| 325 | 
            +
             | 
| 313 326 | 
             
                it 'handles multiple timespans' do
         | 
| 314 327 | 
             
                  WorkingHours::Config.working_hours = {
         | 
| 315 328 | 
             
                    mon: {'07:00' => '12:00', '13:00' => '18:00'}
         | 
| @@ -83,11 +83,11 @@ describe WorkingHours::Config do | |
| 83 83 | 
             
                  it 'rejects invalid time format' do
         | 
| 84 84 | 
             
                    expect {
         | 
| 85 85 | 
             
                      WorkingHours::Config.working_hours = {:mon => {'8:0' => '12:00'}}
         | 
| 86 | 
            -
                    }.to raise_error(WorkingHours::InvalidConfiguration, "Invalid time: 8:0 - must be 'HH:MM'")
         | 
| 86 | 
            +
                    }.to raise_error(WorkingHours::InvalidConfiguration, "Invalid time: 8:0 - must be 'HH:MM(:SS)'")
         | 
| 87 87 |  | 
| 88 88 | 
             
                    expect {
         | 
| 89 | 
            -
                      WorkingHours::Config.working_hours = {:mon => {'08:00' => '24: | 
| 90 | 
            -
                    }.to raise_error(WorkingHours::InvalidConfiguration, "Invalid time: 24: | 
| 89 | 
            +
                      WorkingHours::Config.working_hours = {:mon => {'08:00' => '24:10'}}
         | 
| 90 | 
            +
                    }.to raise_error(WorkingHours::InvalidConfiguration, "Invalid time: 24:10 - outside of day")
         | 
| 91 91 | 
             
                  end
         | 
| 92 92 |  | 
| 93 93 | 
             
                  it 'rejects invalid range' do
         | 
| @@ -107,6 +107,15 @@ describe WorkingHours::Config do | |
| 107 107 | 
             
                      WorkingHours::Config.working_hours = {:mon => {'10:00' => '11:00', '08:00' => '09:00'}}
         | 
| 108 108 | 
             
                    }.not_to raise_error
         | 
| 109 109 | 
             
                  end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                  it 'raises an error when precompiling if working hours are invalid after assignment' do
         | 
| 112 | 
            +
                    WorkingHours::Config.working_hours = {:mon => {'10:00' => '11:00', '08:00' => '09:00'}}
         | 
| 113 | 
            +
                    WorkingHours::Config.working_hours[:mon] = 'Not correct'
         | 
| 114 | 
            +
                    expect {
         | 
| 115 | 
            +
                      1.working.hour.ago
         | 
| 116 | 
            +
                    }.to raise_error(WorkingHours::InvalidConfiguration, 'Invalid type for `mon`: String - must be Hash')
         | 
| 117 | 
            +
                  end
         | 
| 118 | 
            +
             | 
| 110 119 | 
             
                end
         | 
| 111 120 | 
             
              end
         | 
| 112 121 |  | 
| @@ -140,6 +149,15 @@ describe WorkingHours::Config do | |
| 140 149 | 
             
                      WorkingHours::Config.holidays = [Date.today, 42]
         | 
| 141 150 | 
             
                    }.to raise_error(WorkingHours::InvalidConfiguration, "Invalid holiday: 42 - must be Date")
         | 
| 142 151 | 
             
                  end
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                  it 'raises an error when precompiling if holidays are invalid after assignment' do
         | 
| 154 | 
            +
                    WorkingHours::Config.holidays = [Date.today]
         | 
| 155 | 
            +
                    WorkingHours::Config.holidays << 42
         | 
| 156 | 
            +
                    expect {
         | 
| 157 | 
            +
                      1.working.hour.ago
         | 
| 158 | 
            +
                    }.to raise_error(WorkingHours::InvalidConfiguration, 'Invalid holiday: 42 - must be Date')
         | 
| 159 | 
            +
                  end
         | 
| 160 | 
            +
             | 
| 143 161 | 
             
                end
         | 
| 144 162 | 
             
              end
         | 
| 145 163 |  | 
| @@ -178,6 +196,14 @@ describe WorkingHours::Config do | |
| 178 196 | 
             
                      WorkingHours::Config.time_zone = 'Bordeaux'
         | 
| 179 197 | 
             
                    }.to raise_error(WorkingHours::InvalidConfiguration, "Unknown time zone: Bordeaux")
         | 
| 180 198 | 
             
                  end
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                  it 'raises an error when precompiling if timezone is invalid after assignment' do
         | 
| 201 | 
            +
                    WorkingHours::Config.time_zone = 'Paris'
         | 
| 202 | 
            +
                    WorkingHours::Config.holidays << ' NotACity'
         | 
| 203 | 
            +
                    expect {
         | 
| 204 | 
            +
                      1.working.hour.ago
         | 
| 205 | 
            +
                    }.to raise_error(WorkingHours::InvalidConfiguration, 'Invalid holiday:  NotACity - must be Date')
         | 
| 206 | 
            +
                  end
         | 
| 181 207 | 
             
                end
         | 
| 182 208 | 
             
              end
         | 
| 183 209 |  | 
| @@ -192,6 +218,24 @@ describe WorkingHours::Config do | |
| 192 218 | 
             
                    })
         | 
| 193 219 | 
             
                end
         | 
| 194 220 |  | 
| 221 | 
            +
                it 'supports seconds' do
         | 
| 222 | 
            +
                  WorkingHours::Config.working_hours = {:mon => {'20:32:59' => '22:59:59'}}
         | 
| 223 | 
            +
                  expect(subject).to eq({
         | 
| 224 | 
            +
                    :working_hours => [nil, {73979 => 82799}],
         | 
| 225 | 
            +
                    :holidays => Set.new([]),
         | 
| 226 | 
            +
                    :time_zone => ActiveSupport::TimeZone['UTC']
         | 
| 227 | 
            +
                  })
         | 
| 228 | 
            +
                end
         | 
| 229 | 
            +
             | 
| 230 | 
            +
                it 'supports 24:00 (converts to 23:59:59.999999)' do
         | 
| 231 | 
            +
                  WorkingHours::Config.working_hours = {:mon => {'20:00' => '24:00'}}
         | 
| 232 | 
            +
                  expect(subject).to eq({
         | 
| 233 | 
            +
                    :working_hours => [nil, {72000 => 86399.999999}],
         | 
| 234 | 
            +
                    :holidays => Set.new([]),
         | 
| 235 | 
            +
                    :time_zone => ActiveSupport::TimeZone['UTC']
         | 
| 236 | 
            +
                  })
         | 
| 237 | 
            +
                end
         | 
| 238 | 
            +
             | 
| 195 239 | 
             
                it 'changes if working_hours changes' do
         | 
| 196 240 | 
             
                  expect {
         | 
| 197 241 | 
             
                    WorkingHours::Config.working_hours = {:mon => {'08:00' => '14:00'}}
         | 
| @@ -235,4 +279,57 @@ describe WorkingHours::Config do | |
| 235 279 | 
             
                  expect(WorkingHours::Config.precompiled).to be(precompiled)
         | 
| 236 280 | 
             
                end
         | 
| 237 281 | 
             
              end
         | 
| 282 | 
            +
             | 
| 283 | 
            +
              describe '.with_config' do
         | 
| 284 | 
            +
             | 
| 285 | 
            +
                let(:working_hours) { { mon: {'08:00' => '19:00'} } }
         | 
| 286 | 
            +
                let(:holidays) { [Date.new(2014, 11, 15)]}
         | 
| 287 | 
            +
                let(:time_zone) { ActiveSupport::TimeZone.new('Paris') }
         | 
| 288 | 
            +
             | 
| 289 | 
            +
                it 'sets the corresponding config inside the block' do
         | 
| 290 | 
            +
                  WorkingHours::Config.with_config(working_hours: working_hours, holidays: holidays, time_zone: time_zone) do
         | 
| 291 | 
            +
                    expect(WorkingHours::Config.working_hours).to eq(working_hours)
         | 
| 292 | 
            +
                    expect(WorkingHours::Config.holidays).to eq(holidays)
         | 
| 293 | 
            +
                    expect(WorkingHours::Config.time_zone).to eq(time_zone)
         | 
| 294 | 
            +
                  end
         | 
| 295 | 
            +
                end
         | 
| 296 | 
            +
             | 
| 297 | 
            +
                it 'resets to old config after the block' do
         | 
| 298 | 
            +
                  WorkingHours::Config.working_hours = {tue: {'09:00' => '16:00'} }
         | 
| 299 | 
            +
                  WorkingHours::Config.holidays = [Date.new(2014, 01, 01)]
         | 
| 300 | 
            +
                  WorkingHours::Config.time_zone = ActiveSupport::TimeZone.new('Tokyo')
         | 
| 301 | 
            +
                  WorkingHours::Config.with_config(working_hours: working_hours, holidays: holidays, time_zone: time_zone) {}
         | 
| 302 | 
            +
                  expect(WorkingHours::Config.working_hours).to eq({tue: {'09:00' => '16:00'} })
         | 
| 303 | 
            +
                  expect(WorkingHours::Config.holidays).to eq([Date.new(2014, 01, 01)])
         | 
| 304 | 
            +
                  expect(WorkingHours::Config.time_zone).to eq(ActiveSupport::TimeZone.new('Tokyo'))
         | 
| 305 | 
            +
                end
         | 
| 306 | 
            +
             | 
| 307 | 
            +
                it 'resets to old config after the block even if things go bad' do
         | 
| 308 | 
            +
                  WorkingHours::Config.working_hours = {tue: {'09:00' => '16:00'} }
         | 
| 309 | 
            +
                  WorkingHours::Config.holidays = [Date.new(2014, 01, 01)]
         | 
| 310 | 
            +
                  WorkingHours::Config.time_zone = ActiveSupport::TimeZone.new('Tokyo')
         | 
| 311 | 
            +
                  begin
         | 
| 312 | 
            +
                    WorkingHours::Config.with_config(working_hours: working_hours, holidays: holidays, time_zone: time_zone) do
         | 
| 313 | 
            +
                      raise
         | 
| 314 | 
            +
                    end
         | 
| 315 | 
            +
                  rescue
         | 
| 316 | 
            +
                  end
         | 
| 317 | 
            +
                  expect(WorkingHours::Config.working_hours).to eq({tue: {'09:00' => '16:00'} })
         | 
| 318 | 
            +
                  expect(WorkingHours::Config.holidays).to eq([Date.new(2014, 01, 01)])
         | 
| 319 | 
            +
                  expect(WorkingHours::Config.time_zone).to eq(ActiveSupport::TimeZone.new('Tokyo'))
         | 
| 320 | 
            +
                end
         | 
| 321 | 
            +
             | 
| 322 | 
            +
                it 'raises if working_hours are invalid' do
         | 
| 323 | 
            +
                  expect { WorkingHours::Config.with_config(working_hours: {}) {}}.to raise_error(WorkingHours::InvalidConfiguration)
         | 
| 324 | 
            +
                end
         | 
| 325 | 
            +
             | 
| 326 | 
            +
                it 'raises if holidays are invalid' do
         | 
| 327 | 
            +
                  expect { WorkingHours::Config.with_config(holidays: [1]) {}}.to raise_error(WorkingHours::InvalidConfiguration)
         | 
| 328 | 
            +
                end
         | 
| 329 | 
            +
             | 
| 330 | 
            +
                it 'raises if timezone is invalid' do
         | 
| 331 | 
            +
                  expect { WorkingHours::Config.with_config(time_zone: '67P Comet') {}}.to raise_error(WorkingHours::InvalidConfiguration)
         | 
| 332 | 
            +
                end
         | 
| 333 | 
            +
             | 
| 334 | 
            +
              end
         | 
| 238 335 | 
             
            end
         | 
| @@ -28,11 +28,30 @@ describe WorkingHours::CoreExt::DateAndTime do | |
| 28 28 | 
             
                  time + duration
         | 
| 29 29 | 
             
                end
         | 
| 30 30 |  | 
| 31 | 
            -
                it "doesn't break original operator" do
         | 
| 31 | 
            +
                it "doesn't break original Time operator" do
         | 
| 32 32 | 
             
                  time = Time.now
         | 
| 33 33 | 
             
                  expect(WorkingHours).not_to receive(:add_days)
         | 
| 34 34 | 
             
                  expect(time + 3600).to eq(time + 1.hour)
         | 
| 35 35 | 
             
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                it "doesn't break original Date operator" do
         | 
| 38 | 
            +
                  date = Date.today
         | 
| 39 | 
            +
                  expect(WorkingHours).not_to receive(:add_days)
         | 
| 40 | 
            +
                  expect(date + 1).to eq(date + 1.day)
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                it "doesn't break original DateTime operator" do
         | 
| 44 | 
            +
                  datetime = DateTime.now.change(usec: 0)
         | 
| 45 | 
            +
                  expect(WorkingHours).not_to receive(:add_days)
         | 
| 46 | 
            +
                  expect(datetime + 1).to eq(datetime + 1.day)
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                it "doesn't break original TimeWithZone operator" do
         | 
| 50 | 
            +
                  Time.zone = 'UTC'
         | 
| 51 | 
            +
                  time = Time.zone.now
         | 
| 52 | 
            +
                  expect(WorkingHours).not_to receive(:add_days)
         | 
| 53 | 
            +
                  expect(time + 1).to eq(time + 1.second)
         | 
| 54 | 
            +
                end
         | 
| 36 55 | 
             
              end
         | 
| 37 56 |  | 
| 38 57 | 
             
              describe 'operator -' do
         | 
| @@ -60,11 +79,30 @@ describe WorkingHours::CoreExt::DateAndTime do | |
| 60 79 | 
             
                  time - duration
         | 
| 61 80 | 
             
                end
         | 
| 62 81 |  | 
| 63 | 
            -
                it "doesn't break original operator" do
         | 
| 82 | 
            +
                it "doesn't break original Time operator" do
         | 
| 64 83 | 
             
                  time = Time.now
         | 
| 65 84 | 
             
                  expect(WorkingHours).not_to receive(:add_days)
         | 
| 66 85 | 
             
                  expect(time - 3600).to eq(time - 1.hour)
         | 
| 67 86 | 
             
                end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                it "doesn't break original Date operator" do
         | 
| 89 | 
            +
                  date = Date.today
         | 
| 90 | 
            +
                  expect(WorkingHours).not_to receive(:add_days)
         | 
| 91 | 
            +
                  expect(date - 1).to eq(date - 1.day)
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                it "doesn't break original DateTime operator" do
         | 
| 95 | 
            +
                  datetime = DateTime.now.change(usec: 0)
         | 
| 96 | 
            +
                  expect(WorkingHours).not_to receive(:add_days)
         | 
| 97 | 
            +
                  expect(datetime - 1).to eq(datetime - 1.day)
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                it "doesn't break original TimeWithZone operator" do
         | 
| 101 | 
            +
                  Time.zone = 'UTC'
         | 
| 102 | 
            +
                  time = Time.zone.now
         | 
| 103 | 
            +
                  expect(WorkingHours).not_to receive(:add_days)
         | 
| 104 | 
            +
                  expect(time - 1).to eq(time - 1.second)
         | 
| 105 | 
            +
                end
         | 
| 68 106 | 
             
              end
         | 
| 69 107 |  | 
| 70 108 | 
             
              describe '#working_days_until' do
         | 
    
        data/working_hours.gemspec
    CHANGED
    
    | @@ -23,6 +23,6 @@ Gem::Specification.new do |spec| | |
| 23 23 |  | 
| 24 24 | 
             
              spec.add_development_dependency 'bundler', '~> 1.5'
         | 
| 25 25 | 
             
              spec.add_development_dependency 'rake'
         | 
| 26 | 
            -
              spec.add_development_dependency 'rspec', '~> 3. | 
| 26 | 
            +
              spec.add_development_dependency 'rspec', '~> 3.2'
         | 
| 27 27 | 
             
              spec.add_development_dependency 'timecop'
         | 
| 28 28 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: working_hours
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.0. | 
| 4 | 
            +
              version: 1.0.4
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Adrien Jarthon
         | 
| @@ -9,7 +9,7 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date:  | 
| 12 | 
            +
            date: 2015-03-27 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: activesupport
         | 
| @@ -73,14 +73,14 @@ dependencies: | |
| 73 73 | 
             
                requirements:
         | 
| 74 74 | 
             
                - - "~>"
         | 
| 75 75 | 
             
                  - !ruby/object:Gem::Version
         | 
| 76 | 
            -
                    version: '3. | 
| 76 | 
            +
                    version: '3.2'
         | 
| 77 77 | 
             
              type: :development
         | 
| 78 78 | 
             
              prerelease: false
         | 
| 79 79 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 80 80 | 
             
                requirements:
         | 
| 81 81 | 
             
                - - "~>"
         | 
| 82 82 | 
             
                  - !ruby/object:Gem::Version
         | 
| 83 | 
            -
                    version: '3. | 
| 83 | 
            +
                    version: '3.2'
         | 
| 84 84 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 85 85 | 
             
              name: timecop
         | 
| 86 86 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -114,6 +114,7 @@ files: | |
| 114 114 | 
             
            - gemfiles/Gemfile.activesupport-3.2.x
         | 
| 115 115 | 
             
            - gemfiles/Gemfile.activesupport-4.0.x
         | 
| 116 116 | 
             
            - gemfiles/Gemfile.activesupport-4.1.x
         | 
| 117 | 
            +
            - gemfiles/Gemfile.activesupport-4.2.x
         | 
| 117 118 | 
             
            - gemfiles/Gemfile.activesupport-head
         | 
| 118 119 | 
             
            - lib/working_hours.rb
         | 
| 119 120 | 
             
            - lib/working_hours/computation.rb
         | 
| @@ -153,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 153 154 | 
             
                  version: '0'
         | 
| 154 155 | 
             
            requirements: []
         | 
| 155 156 | 
             
            rubyforge_project: 
         | 
| 156 | 
            -
            rubygems_version: 2. | 
| 157 | 
            +
            rubygems_version: 2.4.6
         | 
| 157 158 | 
             
            signing_key: 
         | 
| 158 159 | 
             
            specification_version: 4
         | 
| 159 160 | 
             
            summary: time calculation with working hours
         |