Permalink
Browse files

Merge pull request #692 from attilahorvath/fix-479

[Fix #479] Add support for yearly tasks with custom month values
  • Loading branch information...
2 parents f82c181 + 077754e commit 1dcb91484e6f1ee91c9272daccbe84111754102b @benlangfeld benlangfeld committed on GitHub Mar 3, 2017
Showing with 84 additions and 7 deletions.
  1. +17 −3 lib/whenever/cron.rb
  2. +6 −0 test/test_helper.rb
  3. +61 −4 test/unit/cron_test.rb
View
@@ -63,7 +63,7 @@ def day_given?
def parse_symbol
shortcut = case @time
when *KEYWORDS then "@#{@time}" # :reboot => '@reboot'
- when :year then Whenever.seconds(12, :months)
+ when :year then Whenever.seconds(1, :year)
when :day then Whenever.seconds(1, :day)
when :month then Whenever.seconds(1, :month)
when :week then Whenever.seconds(1, :week)
@@ -104,8 +104,8 @@ def parse_time
timing[1] = @at.is_a?(Time) ? @at.hour : @at
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(12, :months)
- month_frequency = (@time / 30 / 24 / 60 / 60).round
+ 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)
@@ -115,6 +115,20 @@ def parse_time
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
+ timing[2] = if @at.is_a?(Time)
+ day_given? ? @at.day : 1
+ else
+ 1
+ end
+ timing[3] = if @at.is_a?(Time)
+ day_given? ? @at.month : 1
+ else
+ @at.zero? ? 1 : @at
+ end
+ raise ArgumentError, "Month must be between 1-12, #{timing[3]} given" unless (1..12).include?(timing[3])
else
return parse_as_string
end
View
@@ -16,6 +16,12 @@ def two_hours
"0 0,2,4,6,8,10,12,14,16,18,20,22 * * *"
end
+ def assert_months_and_days_and_hours_and_minutes_equals(expected, time, options = {})
+ cron = parse_time(Whenever.seconds(1, :year), 'some task', time, options)
+ minutes, hours, days, months = cron.split(' ')
+ assert_equal expected, [months, days, hours, minutes]
+ end
+
def assert_days_and_hours_and_minutes_equals(expected, time, options = {})
cron = parse_time(Whenever.seconds(2, :months), 'some task', time, options)
minutes, hours, days, _ = cron.split(' ')
View
@@ -208,6 +208,63 @@ class CronParseMonthsTest < Whenever::TestCase
end
end
+class CronParseYearTest < Whenever::TestCase
+ should "parse correctly" do
+ assert_equal '0 0 1 1 *', parse_time(Whenever.seconds(1, :year))
+ end
+
+ should "parse year with a date and/or time" do
+ # should set the day and month to 1 if no date is given
+ assert_equal '0 17 1 1 *', parse_time(Whenever.seconds(1, :year), nil, "5pm")
+ # should use the date if one is given
+ assert_equal '0 2 23 2 *', parse_time(Whenever.seconds(1, :year), nil, "February 23rd at 2am")
+ # should use an iteger as the month
+ assert_equal '0 0 1 5 *', parse_time(Whenever.seconds(1, :year), nil, 5)
+ end
+
+ should "parse correctly when given an 'at' with days, hours, minutes as a Time" do
+ # first param is an array with [months, days, hours, minutes]
+ assert_months_and_days_and_hours_and_minutes_equals %w(1 1 3 45), 'January 1st 3:45am'
+ assert_months_and_days_and_hours_and_minutes_equals %w(2 11 23 0), 'Feb 11 11PM'
+ assert_months_and_days_and_hours_and_minutes_equals %w(3 22 1 1), 'march 22nd at 1:01 am'
+ assert_months_and_days_and_hours_and_minutes_equals %w(3 23 0 0), 'march 22nd at midnight' # looks like midnight means the next day
+ end
+
+ should "parse correctly when given an 'at' with days, hours, minutes as a Time and custom Chronic options are set" do
+ # first param is an array with [months, days, hours, minutes]
+ assert_months_and_days_and_hours_and_minutes_equals %w(2 22 15 45), 'February 22nd 3:45'
+ assert_months_and_days_and_hours_and_minutes_equals %w(2 22 15 45), '02/22 3:45'
+ assert_months_and_days_and_hours_and_minutes_equals %w(2 22 3 45), 'February 22nd 3:45', :chronic_options => { :hours24 => true }
+ assert_months_and_days_and_hours_and_minutes_equals %w(2 22 15 45), 'February 22nd 3:45', :chronic_options => { :hours24 => false }
+
+ assert_months_and_days_and_hours_and_minutes_equals %w(2 3 8 15), '02/03 8:15'
+ assert_months_and_days_and_hours_and_minutes_equals %w(2 3 8 15), '02/03 8:15', :chronic_options => { :endian_precedence => :middle }
+ assert_months_and_days_and_hours_and_minutes_equals %w(3 2 8 15), '02/03 8:15', :chronic_options => { :endian_precedence => :little }
+
+ assert_months_and_days_and_hours_and_minutes_equals %w(3 4 4 50), '03/04 4:50', :chronic_options => { :endian_precedence => :middle, :hours24 => true }
+ assert_months_and_days_and_hours_and_minutes_equals %w(3 4 16 50), '03/04 4:50', :chronic_options => { :endian_precedence => :middle, :hours24 => false }
+ assert_months_and_days_and_hours_and_minutes_equals %w(4 3 4 50), '03/04 4:50', :chronic_options => { :endian_precedence => :little, :hours24 => true }
+ assert_months_and_days_and_hours_and_minutes_equals %w(4 3 16 50), '03/04 4:50', :chronic_options => { :endian_precedence => :little, :hours24 => false }
+ end
+
+ should "parse correctly when given an 'at' with month as an Integer" do
+ # first param is an array with [months, days, hours, minutes]
+ assert_months_and_days_and_hours_and_minutes_equals %w(1 1 0 0), 1
+ assert_months_and_days_and_hours_and_minutes_equals %w(5 1 0 0), 5
+ assert_months_and_days_and_hours_and_minutes_equals %w(12 1 0 0), 12
+ 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)
+ end
+
+ assert_raises ArgumentError do
+ parse_time(Whenever.seconds(1, :year), nil, -1)
+ end
+ end
+end
+
class CronParseDaysOfWeekTest < Whenever::TestCase
should "parse days of the week correctly" do
{
@@ -259,10 +316,10 @@ class CronParseShortcutsTest < Whenever::TestCase
end
should "convert time-based shortcuts to times" do
- assert_equal '0 0 1 * *', parse_time(:month)
- assert_equal '0 0 * * *', parse_time(:day)
- assert_equal '0 * * * *', parse_time(:hour)
- assert_equal '0 0 1 12 *', parse_time(:year)
+ assert_equal '0 0 1 * *', parse_time(:month)
+ assert_equal '0 0 * * *', parse_time(:day)
+ assert_equal '0 * * * *', parse_time(:hour)
+ assert_equal '0 0 1 1 *', parse_time(:year)
assert_equal '0 0 1,8,15,22 * *', parse_time(:week)
end

0 comments on commit 1dcb914

Please sign in to comment.