Skip to content

Commit

Permalink
Add support for mapping Range objects to cron range syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
timcraft committed Nov 20, 2017
1 parent 822525c commit 7860bab
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 8 deletions.
23 changes: 15 additions & 8 deletions lib/whenever/cron.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,26 +96,23 @@ def parse_time
timing[0] = comma_separated_timing(minute_frequency, 59, @at || 0)
when Whenever.seconds(1, :hour)...Whenever.seconds(1, :day)
hour_frequency = (@time / 60 / 60).round
timing[0] = @at.is_a?(Time) ? @at.min : @at
timing[0] = @at.is_a?(Time) ? @at.min : range_or_integer(@at, 0..59, 'Minute')
timing[1] = comma_separated_timing(hour_frequency, 23)
raise ArgumentError, "Minute must be between 0-59, #{timing[0]} given" unless (0..59).include?(timing[0])
when Whenever.seconds(1, :day)...Whenever.seconds(1, :month)
day_frequency = (@time / 24 / 60 / 60).round
timing[0] = @at.is_a?(Time) ? @at.min : 0
timing[1] = @at.is_a?(Time) ? @at.hour : @at
timing[1] = @at.is_a?(Time) ? @at.hour : range_or_integer(@at, 0..23, 'Hour')
timing[2] = comma_separated_timing(day_frequency, 31, 1)
raise ArgumentError, "Hour must be between 0-23, #{timing[1]} given" unless (0..23).include?(timing[1])
when Whenever.seconds(1, :month)...Whenever.seconds(1, :year)
month_frequency = (@time / 30 / 24 / 60 / 60).round
timing[0] = @at.is_a?(Time) ? @at.min : 0
timing[1] = @at.is_a?(Time) ? @at.hour : 0
timing[2] = if @at.is_a?(Time)
day_given? ? @at.day : 1
else
@at.zero? ? 1 : @at
@at == 0 ? 1 : range_or_integer(@at, 1..31, 'Day')
end
timing[3] = comma_separated_timing(month_frequency, 12, 1)
raise ArgumentError, "Day must be between 1-31, #{timing[2]} given" unless (1..31).include?(timing[2])
when Whenever.seconds(1, :year)
timing[0] = @at.is_a?(Time) ? @at.min : 0
timing[1] = @at.is_a?(Time) ? @at.hour : 0
Expand All @@ -127,9 +124,8 @@ def parse_time
timing[3] = if @at.is_a?(Time)
day_given? ? @at.month : 1
else
@at.zero? ? 1 : @at
@at == 0 ? 1 : range_or_integer(@at, 1..12, 'Month')
end
raise ArgumentError, "Month must be between 1-12, #{timing[3]} given" unless (1..12).include?(timing[3])
else
return parse_as_string
end
Expand All @@ -154,6 +150,17 @@ def parse_as_string
raise ArgumentError, "Couldn't parse: #{@time}"
end

def range_or_integer(at, valid_range, name)
must_be_between = "#{name} must be between #{valid_range.min}-#{valid_range.max}"
unless at.is_a?(Range)
raise ArgumentError, "#{must_be_between}, #{at} given" unless valid_range.include?(at)
return at
end
raise ArgumentError, "#{must_be_between}, #{at.min} given" unless valid_range.include?(at.min)
raise ArgumentError, "#{must_be_between}, #{at.max} given" unless valid_range.include?(at.max)
"#{at.min}-#{at.max}"
end

def comma_separated_timing(frequency, max, start = 0)
return start if frequency.nil? || frequency == "" || frequency.zero?
return '*' if frequency == 1
Expand Down
48 changes: 48 additions & 0 deletions test/unit/cron_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ class CronParseHoursTest < Whenever::TestCase
assert_minutes_equals "30", '6:30', :chronic_options => { :hours24 => false }
end

should "parse correctly when given an 'at' with minutes as a Range" do
assert_minutes_equals "15-30", 15..30
end

should "raise an exception when given an 'at' with an invalid minute value" do
assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :hour), nil, 60)
Expand All @@ -86,6 +90,14 @@ class CronParseHoursTest < Whenever::TestCase
assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :hour), nil, -1)
end

assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :hour), nil, 0..60)
end

assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :hour), nil, -1..59)
end
end
end

Expand Down Expand Up @@ -130,6 +142,10 @@ class CronParseDaysTest < Whenever::TestCase
assert_hours_and_minutes_equals %w(23 0), 23
end

should "parse correctly when given an 'at' with hours as a Range" do
assert_hours_and_minutes_equals %w(3-23 0), 3..23
end

should "raise an exception when given an 'at' with an invalid hour value" do
assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :day), nil, 24)
Expand All @@ -138,6 +154,14 @@ class CronParseDaysTest < Whenever::TestCase
assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :day), nil, -1)
end

assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :day), nil, 0..24)
end

assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :day), nil, -1..23)
end
end
end

Expand Down Expand Up @@ -197,6 +221,10 @@ class CronParseMonthsTest < Whenever::TestCase
assert_days_and_hours_and_minutes_equals %w(29 0 0), 29
end

should "parse correctly when given an 'at' with days as a Range" do
assert_days_and_hours_and_minutes_equals %w(1-7 0 0), 1..7
end

should "raise an exception when given an 'at' with an invalid day value" do
assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :month), nil, 32)
Expand All @@ -205,6 +233,14 @@ class CronParseMonthsTest < Whenever::TestCase
assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :month), nil, -1)
end

assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :month), nil, 0..30)
end

assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :month), nil, 1..32)
end
end
end

Expand Down Expand Up @@ -254,6 +290,10 @@ class CronParseYearTest < Whenever::TestCase
assert_months_and_days_and_hours_and_minutes_equals %w(12 1 0 0), 12
end

should "parse correctly when given an 'at' with month as a Range" do
assert_months_and_days_and_hours_and_minutes_equals %w(1-3 1 0 0), 1..3
end

should "raise an exception when given an 'at' with an invalid month value" do
assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :year), nil, 13)
Expand All @@ -262,6 +302,14 @@ class CronParseYearTest < Whenever::TestCase
assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :year), nil, -1)
end

assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :year), nil, 0..12)
end

assert_raises ArgumentError do
parse_time(Whenever.seconds(1, :year), nil, 1..13)
end
end
end

Expand Down

0 comments on commit 7860bab

Please sign in to comment.