whenever 0.8.2 → 1.0.0

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.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.travis.yml +20 -7
  4. data/Appraisals +19 -0
  5. data/CHANGELOG.md +116 -3
  6. data/Gemfile +3 -3
  7. data/LICENSE +2 -2
  8. data/README.md +133 -32
  9. data/Rakefile +3 -10
  10. data/bin/whenever +3 -0
  11. data/bin/wheneverize +8 -5
  12. data/gemfiles/activesupport4.1.gemfile +7 -0
  13. data/gemfiles/activesupport4.2.gemfile +7 -0
  14. data/gemfiles/activesupport5.0.gemfile +7 -0
  15. data/gemfiles/activesupport5.1.gemfile +7 -0
  16. data/gemfiles/activesupport5.2.gemfile +7 -0
  17. data/lib/whenever/capistrano/v2/hooks.rb +8 -0
  18. data/lib/whenever/capistrano/{recipes.rb → v2/recipes.rb} +7 -13
  19. data/lib/whenever/capistrano/{support.rb → v2/support.rb} +12 -0
  20. data/lib/whenever/capistrano/v3/tasks/whenever.rake +56 -0
  21. data/lib/whenever/capistrano.rb +5 -6
  22. data/lib/whenever/command_line.rb +69 -48
  23. data/lib/whenever/cron.rb +54 -25
  24. data/lib/whenever/job.rb +13 -14
  25. data/lib/whenever/job_list.rb +54 -24
  26. data/lib/whenever/numeric.rb +13 -0
  27. data/lib/whenever/numeric_seconds.rb +48 -0
  28. data/lib/whenever/os.rb +7 -0
  29. data/lib/whenever/output_redirection.rb +1 -0
  30. data/lib/whenever/setup.rb +19 -15
  31. data/lib/whenever/version.rb +2 -2
  32. data/lib/whenever.rb +19 -14
  33. data/test/functional/command_line_test.rb +379 -243
  34. data/test/functional/output_at_test.rb +227 -249
  35. data/test/functional/output_default_defined_jobs_test.rb +251 -193
  36. data/test/functional/output_defined_job_test.rb +65 -91
  37. data/test/functional/output_env_test.rb +22 -26
  38. data/test/functional/output_jobs_for_roles_test.rb +46 -65
  39. data/test/functional/output_jobs_with_mailto_test.rb +168 -0
  40. data/test/functional/output_redirection_test.rb +232 -291
  41. data/test/test_case.rb +32 -0
  42. data/test/test_helper.rb +44 -15
  43. data/test/unit/capistrano_support_test.rb +128 -134
  44. data/test/unit/cron_test.rb +373 -208
  45. data/test/unit/executable_test.rb +142 -0
  46. data/test/unit/job_test.rb +111 -117
  47. data/whenever.gemspec +7 -4
  48. metadata +63 -44
@@ -1,253 +1,418 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
1
+ require 'test_helper'
2
2
 
3
- class CronTest < Test::Unit::TestCase
4
-
5
- context "When parsing time in minutes" do
6
- should "raise if less than 1 minute" do
7
- assert_raises ArgumentError do
8
- parse_time(59.seconds)
9
- end
3
+ class CronTest < Whenever::TestCase
4
+ should "raise if less than 1 minute" do
5
+ assert_raises ArgumentError do
6
+ parse_time(Whenever.seconds(59, :seconds))
7
+ end
10
8
 
11
- assert_raises ArgumentError do
12
- parse_time(0.minutes)
13
- end
9
+ assert_raises ArgumentError do
10
+ parse_time(Whenever.seconds(0, :minutes))
14
11
  end
12
+ end
13
+
14
+ # For sanity, do some tests on straight cron-syntax strings
15
+ should "parse correctly" do
16
+ assert_equal '* * * * *', parse_time(Whenever.seconds(1, :minute))
17
+ assert_equal '0,5,10,15,20,25,30,35,40,45,50,55 * * * *', parse_time(Whenever.seconds(5, :minutes))
18
+ assert_equal '7,14,21,28,35,42,49,56 * * * *', parse_time(Whenever.seconds(7, :minutes))
19
+ assert_equal '0,30 * * * *', parse_time(Whenever.seconds(30, :minutes))
20
+ assert_equal '32 * * * *', parse_time(Whenever.seconds(32, :minutes))
21
+ assert '60 * * * *' != parse_time(Whenever.seconds(60, :minutes)) # 60 minutes bumps up into the hour range
22
+ end
23
+
24
+ # Test all minutes
25
+ (2..59).each do |num|
26
+ should "parse correctly for #{num} minutes" do
27
+ start = 0
28
+ start += num unless 60.modulo(num).zero?
29
+ minutes = (start..59).step(num).to_a
15
30
 
16
- # For santity, do some tests on straight String
17
- should "parse correctly" do
18
- assert_equal '* * * * *', parse_time(1.minute)
19
- assert_equal '0,5,10,15,20,25,30,35,40,45,50,55 * * * *', parse_time(5.minutes)
20
- assert_equal '7,14,21,28,35,42,49,56 * * * *', parse_time(7.minutes)
21
- assert_equal '0,30 * * * *', parse_time(30.minutes)
22
- assert_equal '32 * * * *', parse_time(32.minutes)
23
- assert_not_equal '60 * * * *', parse_time(60.minutes) # 60 minutes bumps up into the hour range
31
+ assert_equal "#{minutes.join(',')} * * * *", parse_time(Whenever.seconds(num, :minutes))
24
32
  end
33
+ end
34
+ end
35
+
36
+ class CronParseHoursTest < Whenever::TestCase
37
+ should "parse correctly" do
38
+ assert_equal '0 * * * *', parse_time(Whenever.seconds(1, :hour))
39
+ assert_equal '0 0,2,4,6,8,10,12,14,16,18,20,22 * * *', parse_time(Whenever.seconds(2, :hours))
40
+ assert_equal '0 0,3,6,9,12,15,18,21 * * *', parse_time(Whenever.seconds(3, :hours))
41
+ assert_equal '0 5,10,15,20 * * *', parse_time(Whenever.seconds(5, :hours))
42
+ assert_equal '0 17 * * *', parse_time(Whenever.seconds(17, :hours))
43
+ assert '0 24 * * *' != parse_time(Whenever.seconds(24, :hours)) # 24 hours bumps up into the day range
44
+ end
25
45
 
26
- # Test all minutes
27
- (2..59).each do |num|
28
- should "parse correctly for #{num} minutes" do
29
- start = 0
30
- start += num unless 60.modulo(num).zero?
31
- minutes = (start..59).step(num).to_a
46
+ (2..23).each do |num|
47
+ should "parse correctly for #{num} hours" do
48
+ start = 0
49
+ start += num unless 24.modulo(num).zero?
50
+ hours = (start..23).step(num).to_a
32
51
 
33
- assert_equal "#{minutes.join(',')} * * * *", parse_time(num.minutes)
34
- end
52
+ assert_equal "0 #{hours.join(',')} * * *", parse_time(Whenever.seconds(num, :hours))
35
53
  end
36
54
  end
37
55
 
38
- context "When parsing time in hours" do
39
- should "parse correctly" do
40
- assert_equal '0 * * * *', parse_time(1.hour)
41
- assert_equal '0 0,2,4,6,8,10,12,14,16,18,20,22 * * *', parse_time(2.hours)
42
- assert_equal '0 0,3,6,9,12,15,18,21 * * *', parse_time(3.hours)
43
- assert_equal '0 5,10,15,20 * * *', parse_time(5.hours)
44
- assert_equal '0 17 * * *', parse_time(17.hours)
45
- assert_not_equal '0 24 * * *', parse_time(24.hours) # 24 hours bumps up into the day range
56
+ should "parse correctly when given an 'at' with minutes as an Integer" do
57
+ assert_minutes_equals "1", 1
58
+ assert_minutes_equals "14", 14
59
+ assert_minutes_equals "27", 27
60
+ assert_minutes_equals "55", 55
61
+ end
62
+
63
+ should "parse correctly when given an 'at' with minutes as a Time" do
64
+ # Basically just testing that Chronic parses some times and we get the minutes out of it
65
+ assert_minutes_equals "1", '3:01am'
66
+ assert_minutes_equals "1", 'January 21 2:01 PM'
67
+ assert_minutes_equals "0", 'midnight'
68
+ assert_minutes_equals "59", '13:59'
69
+ end
70
+
71
+ should "parse correctly when given an 'at' with minutes as a Time and custom Chronic options are set" do
72
+ assert_minutes_equals "15", '3:15'
73
+ assert_minutes_equals "15", '3:15', :chronic_options => { :hours24 => true }
74
+ assert_minutes_equals "15", '3:15', :chronic_options => { :hours24 => false }
75
+
76
+ assert_minutes_equals "30", '6:30'
77
+ assert_minutes_equals "30", '6:30', :chronic_options => { :hours24 => true }
78
+ assert_minutes_equals "30", '6:30', :chronic_options => { :hours24 => false }
79
+ end
80
+
81
+ should "parse correctly when given an 'at' with minutes as a Range" do
82
+ assert_minutes_equals "15-30", 15..30
83
+ end
84
+
85
+ should "raise an exception when given an 'at' with an invalid minute value" do
86
+ assert_raises ArgumentError do
87
+ parse_time(Whenever.seconds(1, :hour), nil, 60)
46
88
  end
47
89
 
48
- (2..23).each do |num|
49
- should "parse correctly for #{num} hours" do
50
- start = 0
51
- start += num unless 24.modulo(num).zero?
52
- hours = (start..23).step(num).to_a
90
+ assert_raises ArgumentError do
91
+ parse_time(Whenever.seconds(1, :hour), nil, -1)
92
+ end
53
93
 
54
- assert_equal "0 #{hours.join(',')} * * *", parse_time(num.hours)
55
- end
94
+ assert_raises ArgumentError do
95
+ parse_time(Whenever.seconds(1, :hour), nil, 0..60)
56
96
  end
57
97
 
58
- should "parse correctly when given an 'at' with minutes as an Integer" do
59
- assert_minutes_equals "1", 1
60
- assert_minutes_equals "14", 14
61
- assert_minutes_equals "27", 27
62
- assert_minutes_equals "55", 55
63
- end
64
-
65
- should "parse correctly when given an 'at' with minutes as a Time" do
66
- # Basically just testing that Chronic parses some times and we get the minutes out of it
67
- assert_minutes_equals "1", '3:01am'
68
- assert_minutes_equals "1", 'January 21 2:01 PM'
69
- assert_minutes_equals "0", 'midnight'
70
- assert_minutes_equals "59", '13:59'
71
- end
72
- end
73
-
74
- context "When parsing time in days (of month)" do
75
- should "parse correctly" do
76
- assert_equal '0 0 * * *', parse_time(1.days)
77
- assert_equal '0 0 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31 * *', parse_time(2.days)
78
- assert_equal '0 0 1,5,9,13,17,21,25,29 * *', parse_time(4.days)
79
- assert_equal '0 0 1,8,15,22 * *', parse_time(7.days)
80
- assert_equal '0 0 1,17 * *', parse_time(16.days)
81
- assert_equal '0 0 17 * *', parse_time(17.days)
82
- assert_equal '0 0 29 * *', parse_time(29.days)
83
- assert_not_equal '0 0 30 * *', parse_time(30.days) # 30 days bumps into the month range
84
- end
85
-
86
- should "parse correctly when given an 'at' with hours, minutes as a Time" do
87
- # first param is an array with [hours, minutes]
88
- assert_hours_and_minutes_equals %w(3 45), '3:45am'
89
- assert_hours_and_minutes_equals %w(20 1), '8:01pm'
90
- assert_hours_and_minutes_equals %w(0 0), 'midnight'
91
- assert_hours_and_minutes_equals %w(1 23), '1:23 AM'
92
- assert_hours_and_minutes_equals %w(23 59), 'March 21 11:59 pM'
93
- end
94
-
95
- should "parse correctly when given an 'at' with hours as an Integer" do
96
- # first param is an array with [hours, minutes]
97
- assert_hours_and_minutes_equals %w(1 0), 1
98
- assert_hours_and_minutes_equals %w(3 0), 3
99
- assert_hours_and_minutes_equals %w(15 0), 15
100
- assert_hours_and_minutes_equals %w(19 0), 19
101
- assert_hours_and_minutes_equals %w(23 0), 23
102
- end
103
- end
104
-
105
- context "When parsing time in months" do
106
- should "parse correctly" do
107
- assert_equal '0 0 1 * *', parse_time(1.month)
108
- assert_equal '0 0 1 1,3,5,7,9,11 *', parse_time(2.months)
109
- assert_equal '0 0 1 1,4,7,10 *', parse_time(3.months)
110
- assert_equal '0 0 1 1,5,9 *', parse_time(4.months)
111
- assert_equal '0 0 1 1,6 *', parse_time(5.months)
112
- assert_equal '0 0 1 7 *', parse_time(7.months)
113
- assert_equal '0 0 1 8 *', parse_time(8.months)
114
- assert_equal '0 0 1 9 *', parse_time(9.months)
115
- assert_equal '0 0 1 10 *', parse_time(10.months)
116
- assert_equal '0 0 1 11 *', parse_time(11.months)
117
- assert_equal '0 0 1 12 *', parse_time(12.months)
118
- end
119
-
120
- should "parse months with a date and/or time" do
121
- # should set the day to 1 if no date is given
122
- assert_equal '0 17 1 * *', parse_time(1.month, nil, "5pm")
123
- # should use the date if one is given
124
- assert_equal '0 2 23 * *', parse_time(1.month, nil, "February 23rd at 2am")
125
- # should use an iteger as the day
126
- assert_equal '0 0 5 * *', parse_time(1.month, nil, 5)
127
- end
128
-
129
- should "parse correctly when given an 'at' with days, hours, minutes as a Time" do
130
- # first param is an array with [days, hours, minutes]
131
- assert_days_and_hours_and_minutes_equals %w(1 3 45), 'January 1st 3:45am'
132
- assert_days_and_hours_and_minutes_equals %w(11 23 0), 'Feb 11 11PM'
133
- assert_days_and_hours_and_minutes_equals %w(22 1 1), 'march 22nd at 1:01 am'
134
- assert_days_and_hours_and_minutes_equals %w(23 0 0), 'march 22nd at midnight' # looks like midnight means the next day
135
- end
136
-
137
- should "parse correctly when given an 'at' with days as an Integer" do
138
- # first param is an array with [days, hours, minutes]
139
- assert_days_and_hours_and_minutes_equals %w(1 0 0), 1
140
- assert_days_and_hours_and_minutes_equals %w(15 0 0), 15
141
- assert_days_and_hours_and_minutes_equals %w(29 0 0), 29
142
- end
143
- end
144
-
145
- context "When parsing time in days (of week)" do
146
- should "parse days of the week correctly" do
147
- {
148
- '0' => %w(sun Sunday SUNDAY SUN),
149
- '1' => %w(mon Monday MONDAY MON),
150
- '2' => %w(tue tues Tuesday TUESDAY TUE),
151
- '3' => %w(wed Wednesday WEDNESDAY WED),
152
- '4' => %w(thu thurs thur Thursday THURSDAY THU),
153
- '5' => %w(fri Friday FRIDAY FRI),
154
- '6' => %w(sat Saturday SATURDAY SAT)
155
- }.each do |day, day_tests|
156
- day_tests.each do |day_test|
157
- assert_equal "0 0 * * #{day}", parse_time(day_test)
158
- end
159
- end
98
+ assert_raises ArgumentError do
99
+ parse_time(Whenever.seconds(1, :hour), nil, -1..59)
160
100
  end
101
+ end
102
+ end
103
+
104
+ class CronParseDaysTest < Whenever::TestCase
105
+ should "parse correctly" do
106
+ assert_equal '0 0 * * *', parse_time(Whenever.seconds(1, :days))
107
+ assert_equal '0 0 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31 * *', parse_time(Whenever.seconds(2, :days))
108
+ assert_equal '0 0 1,5,9,13,17,21,25,29 * *', parse_time(Whenever.seconds(4, :days))
109
+ assert_equal '0 0 1,8,15,22 * *', parse_time(Whenever.seconds(7, :days))
110
+ assert_equal '0 0 1,17 * *', parse_time(Whenever.seconds(16, :days))
111
+ assert_equal '0 0 17 * *', parse_time(Whenever.seconds(17, :days))
112
+ assert_equal '0 0 29 * *', parse_time(Whenever.seconds(29, :days))
113
+ assert '0 0 30 * *' != parse_time(Whenever.seconds(30, :days)) # 30 days bumps into the month range
114
+ end
115
+
116
+ should "parse correctly when given an 'at' with hours, minutes as a Time" do
117
+ # first param is an array with [hours, minutes]
118
+ assert_hours_and_minutes_equals %w(3 45), '3:45am'
119
+ assert_hours_and_minutes_equals %w(20 1), '8:01pm'
120
+ assert_hours_and_minutes_equals %w(0 0), 'midnight'
121
+ assert_hours_and_minutes_equals %w(1 23), '1:23 AM'
122
+ assert_hours_and_minutes_equals %w(23 59), 'March 21 11:59 pM'
123
+ end
124
+
125
+ should "parse correctly when given an 'at' with hours, minutes as a Time and custom Chronic options are set" do
126
+ # first param is an array with [hours, minutes]
127
+ assert_hours_and_minutes_equals %w(15 15), '3:15'
128
+ assert_hours_and_minutes_equals %w(3 15), '3:15', :chronic_options => { :hours24 => true }
129
+ assert_hours_and_minutes_equals %w(15 15), '3:15', :chronic_options => { :hours24 => false }
130
+
131
+ assert_hours_and_minutes_equals %w(6 30), '6:30'
132
+ assert_hours_and_minutes_equals %w(6 30), '6:30', :chronic_options => { :hours24 => true }
133
+ assert_hours_and_minutes_equals %w(6 30), '6:30', :chronic_options => { :hours24 => false }
134
+ end
135
+
136
+ should "parse correctly when given an 'at' with hours as an Integer" do
137
+ # first param is an array with [hours, minutes]
138
+ assert_hours_and_minutes_equals %w(1 0), 1
139
+ assert_hours_and_minutes_equals %w(3 0), 3
140
+ assert_hours_and_minutes_equals %w(15 0), 15
141
+ assert_hours_and_minutes_equals %w(19 0), 19
142
+ assert_hours_and_minutes_equals %w(23 0), 23
143
+ end
144
+
145
+ should "parse correctly when given an 'at' with hours as a Range" do
146
+ assert_hours_and_minutes_equals %w(3-23 0), 3..23
147
+ end
161
148
 
162
- should "allow additional directives" do
163
- assert_equal '30 13 * * 5', parse_time('friday', nil, "1:30 pm")
164
- assert_equal '22 2 * * 1', parse_time('Monday', nil, "2:22am")
165
- assert_equal '55 17 * * 4', parse_time('THU', nil, "5:55PM")
149
+ should "raise an exception when given an 'at' with an invalid hour value" do
150
+ assert_raises ArgumentError do
151
+ parse_time(Whenever.seconds(1, :day), nil, 24)
166
152
  end
167
153
 
168
- should "parse weekday correctly" do
169
- assert_equal '0 0 * * 1-5', parse_time('weekday')
170
- assert_equal '0 0 * * 1-5', parse_time('Weekdays')
171
- assert_equal '0 1 * * 1-5', parse_time('Weekdays', nil, "1:00 am")
172
- assert_equal '59 5 * * 1-5', parse_time('Weekdays', nil, "5:59 am")
154
+ assert_raises ArgumentError do
155
+ parse_time(Whenever.seconds(1, :day), nil, -1)
173
156
  end
174
157
 
175
- should "parse weekend correctly" do
176
- assert_equal '0 0 * * 6,0', parse_time('weekend')
177
- assert_equal '0 0 * * 6,0', parse_time('Weekends')
178
- assert_equal '0 7 * * 6,0', parse_time('Weekends', nil, "7am")
179
- assert_equal '2 18 * * 6,0', parse_time('Weekends', nil, "6:02PM")
158
+ assert_raises ArgumentError do
159
+ parse_time(Whenever.seconds(1, :day), nil, 0..24)
180
160
  end
181
- end
182
161
 
183
- context "When parsing time using the cron shortcuts" do
184
- should "parse a :symbol into the correct shortcut" do
185
- assert_equal '@reboot', parse_time(:reboot)
186
- assert_equal '@annually', parse_time(:annually)
187
- assert_equal '@yearly', parse_time(:yearly)
188
- assert_equal '@daily', parse_time(:daily)
189
- assert_equal '@midnight', parse_time(:midnight)
190
- assert_equal '@monthly', parse_time(:monthly)
191
- assert_equal '@weekly', parse_time(:weekly)
192
- assert_equal '@hourly', parse_time(:hourly)
162
+ assert_raises ArgumentError do
163
+ parse_time(Whenever.seconds(1, :day), nil, -1..23)
193
164
  end
165
+ end
166
+ end
167
+
168
+ class CronParseMonthsTest < Whenever::TestCase
169
+ should "parse correctly" do
170
+ assert_equal '0 0 1 * *', parse_time(Whenever.seconds(1, :month))
171
+ assert_equal '0 0 1 1,3,5,7,9,11 *', parse_time(Whenever.seconds(2, :months))
172
+ assert_equal '0 0 1 1,4,7,10 *', parse_time(Whenever.seconds(3, :months))
173
+ assert_equal '0 0 1 1,5,9 *', parse_time(Whenever.seconds(4, :months))
174
+ assert_equal '0 0 1 1,6 *', parse_time(Whenever.seconds(5, :months))
175
+ assert_equal '0 0 1 7 *', parse_time(Whenever.seconds(7, :months))
176
+ assert_equal '0 0 1 8 *', parse_time(Whenever.seconds(8, :months))
177
+ assert_equal '0 0 1 9 *', parse_time(Whenever.seconds(9, :months))
178
+ assert_equal '0 0 1 10 *', parse_time(Whenever.seconds(10, :months))
179
+ assert_equal '0 0 1 11 *', parse_time(Whenever.seconds(11, :months))
180
+ assert_equal '0 0 1 12 *', parse_time(Whenever.seconds(12, :months))
181
+ end
182
+
183
+ should "parse months with a date and/or time" do
184
+ # should set the day to 1 if no date is given
185
+ assert_equal '0 17 1 * *', parse_time(Whenever.seconds(1, :month), nil, "5pm")
186
+ # should use the date if one is given
187
+ assert_equal '0 2 23 * *', parse_time(Whenever.seconds(1, :month), nil, "February 23rd at 2am")
188
+ # should use an iteger as the day
189
+ assert_equal '0 0 5 * *', parse_time(Whenever.seconds(1, :month), nil, 5)
190
+ end
191
+
192
+ should "parse correctly when given an 'at' with days, hours, minutes as a Time" do
193
+ # first param is an array with [days, hours, minutes]
194
+ assert_days_and_hours_and_minutes_equals %w(1 3 45), 'January 1st 3:45am'
195
+ assert_days_and_hours_and_minutes_equals %w(11 23 0), 'Feb 11 11PM'
196
+ assert_days_and_hours_and_minutes_equals %w(22 1 1), 'march 22nd at 1:01 am'
197
+ assert_days_and_hours_and_minutes_equals %w(23 0 0), 'march 22nd at midnight' # looks like midnight means the next day
198
+ end
199
+
200
+ should "parse correctly when given an 'at' with days, hours, minutes as a Time and custom Chronic options are set" do
201
+ # first param is an array with [days, hours, minutes]
202
+ assert_days_and_hours_and_minutes_equals %w(22 15 45), 'February 22nd 3:45'
203
+ assert_days_and_hours_and_minutes_equals %w(22 15 45), '02/22 3:45'
204
+ assert_days_and_hours_and_minutes_equals %w(22 3 45), 'February 22nd 3:45', :chronic_options => { :hours24 => true }
205
+ assert_days_and_hours_and_minutes_equals %w(22 15 45), 'February 22nd 3:45', :chronic_options => { :hours24 => false }
206
+
207
+ assert_days_and_hours_and_minutes_equals %w(3 8 15), '02/03 8:15'
208
+ assert_days_and_hours_and_minutes_equals %w(3 8 15), '02/03 8:15', :chronic_options => { :endian_precedence => :middle }
209
+ assert_days_and_hours_and_minutes_equals %w(2 8 15), '02/03 8:15', :chronic_options => { :endian_precedence => :little }
210
+
211
+ assert_days_and_hours_and_minutes_equals %w(4 4 50), '03/04 4:50', :chronic_options => { :endian_precedence => :middle, :hours24 => true }
212
+ assert_days_and_hours_and_minutes_equals %w(4 16 50), '03/04 4:50', :chronic_options => { :endian_precedence => :middle, :hours24 => false }
213
+ assert_days_and_hours_and_minutes_equals %w(3 4 50), '03/04 4:50', :chronic_options => { :endian_precedence => :little, :hours24 => true }
214
+ assert_days_and_hours_and_minutes_equals %w(3 16 50), '03/04 4:50', :chronic_options => { :endian_precedence => :little, :hours24 => false }
215
+ end
216
+
217
+ should "parse correctly when given an 'at' with days as an Integer" do
218
+ # first param is an array with [days, hours, minutes]
219
+ assert_days_and_hours_and_minutes_equals %w(1 0 0), 1
220
+ assert_days_and_hours_and_minutes_equals %w(15 0 0), 15
221
+ assert_days_and_hours_and_minutes_equals %w(29 0 0), 29
222
+ end
194
223
 
195
- should "convert time-based shortcuts to times" do
196
- assert_equal '0 0 1 * *', parse_time(:month)
197
- assert_equal '0 0 * * *', parse_time(:day)
198
- assert_equal '0 * * * *', parse_time(:hour)
199
- assert_equal '0 0 1 12 *', parse_time(:year)
200
- assert_equal '0 0 1,8,15,22 * *', parse_time(:week)
224
+ should "parse correctly when given an 'at' with days as a Range" do
225
+ assert_days_and_hours_and_minutes_equals %w(1-7 0 0), 1..7
226
+ end
227
+
228
+ should "raise an exception when given an 'at' with an invalid day value" do
229
+ assert_raises ArgumentError do
230
+ parse_time(Whenever.seconds(1, :month), nil, 32)
201
231
  end
202
232
 
203
- should "raise an exception if a valid shortcut is given but also an :at" do
204
- assert_raises ArgumentError do
205
- parse_time(:hourly, nil, "1:00 am")
206
- end
233
+ assert_raises ArgumentError do
234
+ parse_time(Whenever.seconds(1, :month), nil, -1)
235
+ end
207
236
 
208
- assert_raises ArgumentError do
209
- parse_time(:reboot, nil, 5)
210
- end
237
+ assert_raises ArgumentError do
238
+ parse_time(Whenever.seconds(1, :month), nil, 0..30)
239
+ end
211
240
 
212
- assert_raises ArgumentError do
213
- parse_time(:daily, nil, '4:20pm')
214
- end
241
+ assert_raises ArgumentError do
242
+ parse_time(Whenever.seconds(1, :month), nil, 1..32)
215
243
  end
216
244
  end
245
+ end
246
+
247
+ class CronParseYearTest < Whenever::TestCase
248
+ should "parse correctly" do
249
+ assert_equal '0 0 1 1 *', parse_time(Whenever.seconds(1, :year))
250
+ end
251
+
252
+ should "parse year with a date and/or time" do
253
+ # should set the day and month to 1 if no date is given
254
+ assert_equal '0 17 1 1 *', parse_time(Whenever.seconds(1, :year), nil, "5pm")
255
+ # should use the date if one is given
256
+ assert_equal '0 2 23 2 *', parse_time(Whenever.seconds(1, :year), nil, "February 23rd at 2am")
257
+ # should use an iteger as the month
258
+ assert_equal '0 0 1 5 *', parse_time(Whenever.seconds(1, :year), nil, 5)
259
+ end
260
+
261
+ should "parse correctly when given an 'at' with days, hours, minutes as a Time" do
262
+ # first param is an array with [months, days, hours, minutes]
263
+ assert_months_and_days_and_hours_and_minutes_equals %w(1 1 3 45), 'January 1st 3:45am'
264
+ assert_months_and_days_and_hours_and_minutes_equals %w(2 11 23 0), 'Feb 11 11PM'
265
+ assert_months_and_days_and_hours_and_minutes_equals %w(3 22 1 1), 'march 22nd at 1:01 am'
266
+ 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
267
+ end
268
+
269
+ should "parse correctly when given an 'at' with days, hours, minutes as a Time and custom Chronic options are set" do
270
+ # first param is an array with [months, days, hours, minutes]
271
+ assert_months_and_days_and_hours_and_minutes_equals %w(2 22 15 45), 'February 22nd 3:45'
272
+ assert_months_and_days_and_hours_and_minutes_equals %w(2 22 15 45), '02/22 3:45'
273
+ assert_months_and_days_and_hours_and_minutes_equals %w(2 22 3 45), 'February 22nd 3:45', :chronic_options => { :hours24 => true }
274
+ assert_months_and_days_and_hours_and_minutes_equals %w(2 22 15 45), 'February 22nd 3:45', :chronic_options => { :hours24 => false }
275
+
276
+ assert_months_and_days_and_hours_and_minutes_equals %w(2 3 8 15), '02/03 8:15'
277
+ assert_months_and_days_and_hours_and_minutes_equals %w(2 3 8 15), '02/03 8:15', :chronic_options => { :endian_precedence => :middle }
278
+ assert_months_and_days_and_hours_and_minutes_equals %w(3 2 8 15), '02/03 8:15', :chronic_options => { :endian_precedence => :little }
279
+
280
+ 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 }
281
+ 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 }
282
+ 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 }
283
+ 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 }
284
+ end
285
+
286
+ should "parse correctly when given an 'at' with month as an Integer" do
287
+ # first param is an array with [months, days, hours, minutes]
288
+ assert_months_and_days_and_hours_and_minutes_equals %w(1 1 0 0), 1
289
+ assert_months_and_days_and_hours_and_minutes_equals %w(5 1 0 0), 5
290
+ assert_months_and_days_and_hours_and_minutes_equals %w(12 1 0 0), 12
291
+ end
292
+
293
+ should "parse correctly when given an 'at' with month as a Range" do
294
+ assert_months_and_days_and_hours_and_minutes_equals %w(1-3 1 0 0), 1..3
295
+ end
296
+
297
+ should "raise an exception when given an 'at' with an invalid month value" do
298
+ assert_raises ArgumentError do
299
+ parse_time(Whenever.seconds(1, :year), nil, 13)
300
+ end
301
+
302
+ assert_raises ArgumentError do
303
+ parse_time(Whenever.seconds(1, :year), nil, -1)
304
+ end
305
+
306
+ assert_raises ArgumentError do
307
+ parse_time(Whenever.seconds(1, :year), nil, 0..12)
308
+ end
217
309
 
218
- context "When given raw cron sytax" do
219
- should "return the same cron sytax" do
220
- crons = ['0 0 27-31 * *', '* * * * *', '2/3 1,9,22 11-26 1-6 *',
221
- "*\t*\t*\t*\t*",
222
- '@reboot', '@yearly', '@annually', '@monthly', '@weekly',
223
- '@daily', '@midnight', '@hourly']
224
- crons.each do |cron|
225
- assert_equal cron, parse_time(cron)
310
+ assert_raises ArgumentError do
311
+ parse_time(Whenever.seconds(1, :year), nil, 1..13)
312
+ end
313
+ end
314
+ end
315
+
316
+ class CronParseDaysOfWeekTest < Whenever::TestCase
317
+ should "parse days of the week correctly" do
318
+ {
319
+ '0' => %w(sun Sunday SUNDAY SUN),
320
+ '1' => %w(mon Monday MONDAY MON),
321
+ '2' => %w(tue tues Tuesday TUESDAY TUE),
322
+ '3' => %w(wed Wednesday WEDNESDAY WED),
323
+ '4' => %w(thu thurs thur Thursday THURSDAY THU),
324
+ '5' => %w(fri Friday FRIDAY FRI),
325
+ '6' => %w(sat Saturday SATURDAY SAT)
326
+ }.each do |day, day_tests|
327
+ day_tests.each do |day_test|
328
+ assert_equal "0 0 * * #{day}", parse_time(day_test)
226
329
  end
227
330
  end
228
331
  end
229
332
 
230
- private
333
+ should "allow additional directives" do
334
+ assert_equal '30 13 * * 5', parse_time('friday', nil, "1:30 pm")
335
+ assert_equal '22 2 * * 1', parse_time('Monday', nil, "2:22am")
336
+ assert_equal '55 17 * * 4', parse_time('THU', nil, "5:55PM")
337
+ end
338
+
339
+ should "parse weekday correctly" do
340
+ assert_equal '0 0 * * 1-5', parse_time('weekday')
341
+ assert_equal '0 0 * * 1-5', parse_time('Weekdays')
342
+ assert_equal '0 1 * * 1-5', parse_time('Weekdays', nil, "1:00 am")
343
+ assert_equal '59 5 * * 1-5', parse_time('Weekdays', nil, "5:59 am")
344
+ end
345
+
346
+ should "parse weekend correctly" do
347
+ assert_equal '0 0 * * 6,0', parse_time('weekend')
348
+ assert_equal '0 0 * * 6,0', parse_time('Weekends')
349
+ assert_equal '0 7 * * 6,0', parse_time('Weekends', nil, "7am")
350
+ assert_equal '2 18 * * 6,0', parse_time('Weekends', nil, "6:02PM")
351
+ end
352
+ end
353
+
354
+ class CronParseShortcutsTest < Whenever::TestCase
355
+ should "parse a :symbol into the correct shortcut" do
356
+ assert_equal '@reboot', parse_time(:reboot)
357
+ assert_equal '@annually', parse_time(:annually)
358
+ assert_equal '@yearly', parse_time(:yearly)
359
+ assert_equal '@daily', parse_time(:daily)
360
+ assert_equal '@midnight', parse_time(:midnight)
361
+ assert_equal '@monthly', parse_time(:monthly)
362
+ assert_equal '@weekly', parse_time(:weekly)
363
+ assert_equal '@hourly', parse_time(:hourly)
364
+ end
365
+
366
+ should "convert time-based shortcuts to times" do
367
+ assert_equal '0 0 1 * *', parse_time(:month)
368
+ assert_equal '0 0 * * *', parse_time(:day)
369
+ assert_equal '0 * * * *', parse_time(:hour)
370
+ assert_equal '0 0 1 1 *', parse_time(:year)
371
+ assert_equal '0 0 1,8,15,22 * *', parse_time(:week)
372
+ end
373
+
374
+ should "raise an exception if a valid shortcut is given but also an :at" do
375
+ assert_raises ArgumentError do
376
+ parse_time(:hourly, nil, "1:00 am")
377
+ end
378
+
379
+ assert_raises ArgumentError do
380
+ parse_time(:reboot, nil, 5)
381
+ end
231
382
 
232
- def assert_days_and_hours_and_minutes_equals(expected, time)
233
- cron = parse_time(2.months, 'some task', time)
234
- minutes, hours, days, *garbage = cron.split(' ')
235
- assert_equal expected, [days, hours, minutes]
383
+ assert_raises ArgumentError do
384
+ parse_time(:daily, nil, '4:20pm')
385
+ end
236
386
  end
387
+ end
237
388
 
238
- def assert_hours_and_minutes_equals(expected, time)
239
- cron = parse_time(2.days, 'some task', time)
240
- minutes, hours, *garbage = cron.split(' ')
241
- assert_equal expected, [hours, minutes]
389
+ class CronParseRubyTimeTest < Whenever::TestCase
390
+ should "process things like `1.day` correctly" do
391
+ assert_equal "0 0 * * *", parse_time(1.day)
242
392
  end
393
+ end
243
394
 
244
- def assert_minutes_equals(expected, time)
245
- cron = parse_time(2.hours, 'some task', time)
246
- assert_equal expected, cron.split(' ')[0]
395
+ class CronParseRawTest < Whenever::TestCase
396
+ should "raise if cron-syntax string is too long" do
397
+ assert_raises ArgumentError do
398
+ parse_time('* * * * * *')
399
+ end
247
400
  end
248
401
 
249
- def parse_time(time = nil, task = nil, at = nil)
250
- Whenever::Output::Cron.new(time, task, at).time_in_cron_syntax
402
+ should "raise if cron-syntax string is invalid" do
403
+ assert_raises ArgumentError do
404
+ parse_time('** * * * *')
405
+ end
251
406
  end
252
407
 
253
- end
408
+ should "return the same cron sytax" do
409
+ crons = ['0 0 27-31 * *', '* * * * *', '2/3 1,9,22 11-26 1-6 *', '*/5 6-23 * * *',
410
+ "*\t*\t*\t*\t*",
411
+ '7 17 * * FRI', '7 17 * * Mon-Fri', '30 12 * Jun *', '30 12 * Jun-Aug *',
412
+ '@reboot', '@yearly', '@annually', '@monthly', '@weekly',
413
+ '@daily', '@midnight', '@hourly']
414
+ crons.each do |cron|
415
+ assert_equal cron, parse_time(cron)
416
+ end
417
+ end
418
+ end