diff --git a/Gemfile.lock b/Gemfile.lock index ce1afdf..98980ae 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - tod (2.0.0) + tod (2.0.1) GEM remote: https://rubygems.org/ diff --git a/lib/tod/shift.rb b/lib/tod/shift.rb index 4cee77c..3903bdb 100644 --- a/lib/tod/shift.rb +++ b/lib/tod/shift.rb @@ -33,9 +33,20 @@ def include?(tod) # Returns true if ranges overlap, false otherwise. def overlaps?(other) + max_seconds = TimeOfDay::NUM_SECONDS_IN_DAY + + # Standard case, when Shifts are on the same day a, b = [self, other].map(&:range).sort_by(&:first) op = a.exclude_end? ? :> : :>= - a.last.send(op, b.first) + return true if a.last.send(op, b.first) + + # Special cases, when Shifts span to the next day + return false if (a.last < max_seconds) && (b.last < max_seconds) + + a = Range.new(a.first, a.last - max_seconds, a.exclude_end?) if a.last > max_seconds + b = Range.new(b.first, b.last - max_seconds, b.exclude_end?) if b.last > max_seconds + a, b = [a, b].sort_by(&:last) + b.last.send(op, a.last) && a.last.send(op, b.first) end def contains?(shift) diff --git a/lib/tod/time_of_day.rb b/lib/tod/time_of_day.rb index 4707820..95ac455 100644 --- a/lib/tod/time_of_day.rb +++ b/lib/tod/time_of_day.rb @@ -2,7 +2,7 @@ module Tod class TimeOfDay include Comparable - attr_reader :hour, :minute, :second, :second_of_day + attr_reader :hour, :minute, :second, :second_of_day, :day, :month, :year alias_method :min, :minute alias_method :sec, :second alias_method :to_i, :second_of_day @@ -46,6 +46,9 @@ def initialize(h, m=0, s=0) @hour = Integer(h) @minute = Integer(m) @second = Integer(s) + @day = Integer(1) + @month = Integer(1) + @year = Integer(2000) raise ArgumentError, "hour must be between 0 and 23" unless (0..23).include?(@hour) raise ArgumentError, "minute must be between 0 and 59" unless (0..59).include?(@minute) diff --git a/test/tod/shift_test.rb b/test/tod/shift_test.rb index 0a1f7e0..433fa93 100644 --- a/test/tod/shift_test.rb +++ b/test/tod/shift_test.rb @@ -43,12 +43,49 @@ shift1 = Tod::Shift.new(Tod::TimeOfDay.new(12), Tod::TimeOfDay.new(18)) shift2 = Tod::Shift.new(Tod::TimeOfDay.new(13), Tod::TimeOfDay.new(15)) assert shift1.overlaps?(shift2) + + # Additional Testing for Shifts that span from one day to another + cases = [ + [5, 8, 7, 2], + [7, 2, 1, 8], + [7, 2, 5, 8], + [4, 8, 1, 5], + [1, 5, 4, 8], + [7, 2, 1, 4], + [1, 4, 7, 2], + [1, 4, 3, 2], + [5, 8, 7, 2], + [7, 2, 8, 3], + [7, 2, 6, 3], + [7, 2, 1, 8] + ] + + cases.each do |c| + shift1 = Tod::Shift.new(Tod::TimeOfDay.new(c[0]), Tod::TimeOfDay.new(c[1])) + shift2 = Tod::Shift.new(Tod::TimeOfDay.new(c[2]), Tod::TimeOfDay.new(c[3])) + assert shift1.overlaps?(shift2), "Failed with args: #{c}" + end end it "is false when shifts don't overlap" do shift1 = Tod::Shift.new(Tod::TimeOfDay.new(1), Tod::TimeOfDay.new(5)) shift2 = Tod::Shift.new(Tod::TimeOfDay.new(9), Tod::TimeOfDay.new(12)) refute shift1.overlaps?(shift2) + + # Additional Testing for Shifts that span from one day to another + cases = [ + [7, 8, 1, 5], + [1, 5, 7, 8], + [7, 2, 3, 4], + [3, 4, 5, 2], + [1, 5, 9, 12] + ] + + cases.each do |c| + shift1 = Tod::Shift.new(Tod::TimeOfDay.new(c[0]), Tod::TimeOfDay.new(c[1])) + shift2 = Tod::Shift.new(Tod::TimeOfDay.new(c[2]), Tod::TimeOfDay.new(c[3])) + refute shift1.overlaps?(shift2), "Failed with args: #{c}" + end end it "is true when shifts touch with inclusive end" do