Skip to content

Commit

Permalink
Increase code safety by always initializing an empty hash for each da…
Browse files Browse the repository at this point in the history
…y of the week in the precompiled config
  • Loading branch information
jarthod committed Jan 31, 2021
1 parent 143adc9 commit b14d400
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,7 @@

# v1.3.0
* Improve supports for fractional seconds in input times by only rounding results at the end - [#42](https://github.com/Intrepidd/working_hours/issues/42) [#43](https://github.com/Intrepidd/working_hours/pull/43)
* Increase code safety by always initializing an empty hash for each day of the week in the precompiled config (inspired by [#35](https://github.com/Intrepidd/working_hours/pull/35)

# v1.2.0
* Drop support for ruby 2.0, 2.1, 2.2 and 2.3
Expand Down
6 changes: 3 additions & 3 deletions lib/working_hours/computation.rb
Expand Up @@ -80,7 +80,7 @@ def advance_to_working_time time, config: nil
end
# find first working range after time
time_in_day = time.seconds_since_midnight
(config[:working_hours][time.wday] || {}).each do |from, to|
config[:working_hours][time.wday].each do |from, to|
return time if time_in_day >= from and time_in_day < to
return time + (from - time_in_day) if from >= time_in_day
end
Expand All @@ -100,7 +100,7 @@ def advance_to_closing_time time, config: nil
# find next working range after time
time_in_day = time.seconds_since_midnight
time = time.beginning_of_day
(config[:working_hours][time.wday] || {}).each do |from, to|
config[:working_hours][time.wday].each do |from, to|
return time + to if time_in_day >= from and time_in_day < to
return time + to if from >= time_in_day
end
Expand Down Expand Up @@ -131,7 +131,7 @@ def return_to_exact_working_time time, config: nil
end
# find last working range before time
time_in_day = time.seconds_since_midnight
(config[:working_hours][time.wday] || {}).reverse_each do |from, to|
config[:working_hours][time.wday].reverse_each do |from, to|
# round is used to suppress miliseconds hack from `end_of_day`
return time if time_in_day > from and time_in_day <= to
return (time - (time_in_day - to)) if to <= time_in_day
Expand Down
3 changes: 1 addition & 2 deletions lib/working_hours/config.rb
Expand Up @@ -44,9 +44,8 @@ def precompiled
validate_working_hours! config[:working_hours]
validate_holidays! config[:holidays]
validate_time_zone! config[:time_zone]
compiled = {working_hours: []}
compiled = { working_hours: Array.new(7) { Hash.new } }
working_hours.each do |day, hours|
compiled[:working_hours][DAYS_OF_WEEK.index(day)] = {}
hours.each do |start, finish|
compiled[:working_hours][DAYS_OF_WEEK.index(day)][compile_time(start)] = compile_time(finish)
end
Expand Down
17 changes: 12 additions & 5 deletions spec/working_hours/config_spec.rb
Expand Up @@ -266,16 +266,23 @@

it 'computes an optimized version' do
expect(subject).to eq({
:working_hours => [nil, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}],
:working_hours => [{}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {}],
:holidays => Set.new([]),
:time_zone => ActiveSupport::TimeZone['UTC']
})
end

it 'includes default values for each days so computation does not fail' do
WorkingHours::Config.working_hours = {:mon => {'08:00' => '14:00'}}
expect(subject[:working_hours]).to eq([{}, {28800=>50400}, {}, {}, {}, {}, {}])
expect(WorkingHours.working_time_between(Time.utc(2014, 4, 14, 0), Time.utc(2014, 4, 21, 0))).to eq(3600*6)
expect(WorkingHours.add_seconds(Time.utc(2014, 4, 14, 0), 3600*7)).to eq(Time.utc(2014, 4, 21, 9))
end

it 'supports seconds' do
WorkingHours::Config.working_hours = {:mon => {'20:32:59' => '22:59:59'}}
expect(subject).to eq({
:working_hours => [nil, {73979 => 82799}],
:working_hours => [{}, {73979 => 82799}, {}, {}, {}, {}, {}],
:holidays => Set.new([]),
:time_zone => ActiveSupport::TimeZone['UTC']
})
Expand All @@ -284,7 +291,7 @@
it 'supports 24:00 (converts to 23:59:59.999999)' do
WorkingHours::Config.working_hours = {:mon => {'20:00' => '24:00'}}
expect(subject).to eq({
:working_hours => [nil, {72000 => 86399.999999}],
:working_hours => [{}, {72000 => 86399.999999}, {}, {}, {}, {}, {}],
:holidays => Set.new([]),
:time_zone => ActiveSupport::TimeZone['UTC']
})
Expand All @@ -296,9 +303,9 @@
}.to change {
WorkingHours::Config.precompiled[:working_hours]
}.from(
[nil, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}]
[{}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {}]
).to(
[nil, {28800=>50400}]
[{}, {28800=>50400}, {}, {}, {}, {}, {}]
)
end

Expand Down

0 comments on commit b14d400

Please sign in to comment.