parse-cron 0.1.2 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +1 -0
- data/License +21 -0
- data/README.md +17 -0
- data/lib/cron_parser.rb +63 -23
- data/lib/parse-cron/version.rb +1 -1
- data/spec/cron_parser_spec.rb +119 -39
- metadata +9 -13
- data/README +0 -5
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NDU3MTY0MGQ1YWE1YTlmNjVhODMzZDk2MjgxMzFiMDNhOGE2OWNmNA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OGQ0ZmJlMTZlNTU0MDk1YmY4YjFhMzBhNWE4YTM2N2VjNDg2Yjc3MA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
Mzg4N2NiZTNhNWI2NDcwYTEwNTJkMGU5NDI3ZGRmMmVmOTkwY2E4ZGZmOGY5
|
10
|
+
MjQ0NDI2YTA5N2Y2YWUzNmRlZTNjOGM3NmUyMmIzY2YxOWRlZWJiMGIwYmQ1
|
11
|
+
YzE5YmIzMDc0NGM4ZTYzZWJiYWQ3MWM1NTA4NWIzN2U4MGQ3NDM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ODRhNDM0ZTUyOTBlN2ZhNzkzNjc0NzdhYTA2NTMzY2ZjZTQ0MTVjZTE4ZDM4
|
14
|
+
YTBjNWQ2MzFkMmFmYjk0YjdmZjA3NzlmZWUxYzIyNGQyNWRhNDUyMDk4NGY4
|
15
|
+
NDQzNTMxMThlMDllYzgzODJjMmNkYTkxZDc1MTFiMDk3OTg0OTc=
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/License
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (C) 2013 Michael Siebert <siebertm85@googlemail.com>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without restriction,
|
6
|
+
including without limitation the rights to use, copy, modify,
|
7
|
+
merge, publish, distribute, sublicense, and/or sell copies of
|
8
|
+
the Software, and to permit persons to whom the Software is
|
9
|
+
furnished to do so, subject to the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall
|
12
|
+
be included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
16
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
18
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
19
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
20
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
21
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# parse-cron - parse crontab syntax & determine next scheduled run [![Build Status](https://travis-ci.org/siebertm/parse-cron.png)](https://travis-ci.org/siebertm/parse-cron)
|
2
|
+
|
3
|
+
The goal of this gem is to parse a crontab timing specification and determine when the
|
4
|
+
job should be run. It is not a scheduler, it does not run the jobs.
|
5
|
+
|
6
|
+
## API example
|
7
|
+
|
8
|
+
```
|
9
|
+
cron_parser = CronParser.new('30 * * * *')
|
10
|
+
|
11
|
+
# Comming times
|
12
|
+
next_comming_time = cron_parser.next(Time.now)
|
13
|
+
|
14
|
+
# Times that have been
|
15
|
+
most_resently_time = cron_parser.last(Time.now)
|
16
|
+
```
|
17
|
+
|
data/lib/cron_parser.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'set'
|
2
|
+
require 'date'
|
2
3
|
#
|
3
4
|
# Parses cron expressions and computes the next occurence of the "job"
|
4
5
|
#
|
@@ -28,18 +29,18 @@ class CronParser
|
|
28
29
|
end
|
29
30
|
|
30
31
|
SYMBOLS = {
|
31
|
-
"jan" => "
|
32
|
-
"feb" => "
|
33
|
-
"mar" => "
|
34
|
-
"apr" => "
|
35
|
-
"may" => "
|
36
|
-
"jun" => "
|
37
|
-
"jul" => "
|
38
|
-
"aug" => "
|
39
|
-
"sep" => "
|
40
|
-
"oct" => "
|
41
|
-
"nov" => "
|
42
|
-
"dec" => "
|
32
|
+
"jan" => "1",
|
33
|
+
"feb" => "2",
|
34
|
+
"mar" => "3",
|
35
|
+
"apr" => "4",
|
36
|
+
"may" => "5",
|
37
|
+
"jun" => "6",
|
38
|
+
"jul" => "7",
|
39
|
+
"aug" => "8",
|
40
|
+
"sep" => "9",
|
41
|
+
"oct" => "10",
|
42
|
+
"nov" => "11",
|
43
|
+
"dec" => "12",
|
43
44
|
|
44
45
|
"sun" => "0",
|
45
46
|
"mon" => "1",
|
@@ -51,14 +52,34 @@ class CronParser
|
|
51
52
|
}
|
52
53
|
|
53
54
|
def initialize(source,time_source = Time)
|
54
|
-
@source = source
|
55
|
+
@source = interpret_vixieisms(source)
|
55
56
|
@time_source = time_source
|
57
|
+
validate_source
|
58
|
+
end
|
59
|
+
|
60
|
+
def interpret_vixieisms(spec)
|
61
|
+
case spec
|
62
|
+
when '@reboot'
|
63
|
+
raise ArgumentError, "Can't predict last/next run of @reboot"
|
64
|
+
when '@yearly', '@annually'
|
65
|
+
'0 0 1 1 *'
|
66
|
+
when '@monthly'
|
67
|
+
'0 0 1 * *'
|
68
|
+
when '@weekly'
|
69
|
+
'0 0 * * 0'
|
70
|
+
when '@daily', '@midnight'
|
71
|
+
'0 0 * * *'
|
72
|
+
when '@hourly'
|
73
|
+
'0 * * * *'
|
74
|
+
else
|
75
|
+
spec
|
76
|
+
end
|
56
77
|
end
|
57
78
|
|
58
79
|
|
59
80
|
# returns the next occurence after the given date
|
60
81
|
def next(now = @time_source.now)
|
61
|
-
t = InternalTime.new(now
|
82
|
+
t = InternalTime.new(now, @time_source)
|
62
83
|
|
63
84
|
unless time_specs[:month][0].include?(t.month)
|
64
85
|
nudge_month(t)
|
@@ -114,25 +135,25 @@ class CronParser
|
|
114
135
|
else
|
115
136
|
if SUBELEMENT_REGEX === subel
|
116
137
|
if $5 # with range
|
117
|
-
stepped_range($1.to_i
|
138
|
+
stepped_range($1.to_i..$3.to_i, $5.to_i)
|
118
139
|
elsif $3 # range without step
|
119
|
-
stepped_range($1.to_i
|
140
|
+
stepped_range($1.to_i..$3.to_i, 1)
|
120
141
|
else # just a numeric
|
121
142
|
[$1.to_i]
|
122
143
|
end
|
123
144
|
else
|
124
|
-
raise "Bad Vixie-style specification #{subel}"
|
145
|
+
raise ArgumentError, "Bad Vixie-style specification #{subel}"
|
125
146
|
end
|
126
147
|
end
|
127
148
|
end.flatten.sort
|
128
149
|
|
129
|
-
[Set.new(values), values]
|
150
|
+
[Set.new(values), values, elem]
|
130
151
|
end
|
131
152
|
|
132
153
|
|
133
154
|
protected
|
134
155
|
|
135
|
-
# returns a list of days which do both match time_spec[:dom]
|
156
|
+
# returns a list of days which do both match time_spec[:dom] or time_spec[:dow]
|
136
157
|
def interpolate_weekdays(year, month)
|
137
158
|
@_interpolate_weekdays_cache ||= {}
|
138
159
|
@_interpolate_weekdays_cache["#{year}-#{month}"] ||= interpolate_weekdays_without_cache(year, month)
|
@@ -140,12 +161,21 @@ class CronParser
|
|
140
161
|
|
141
162
|
def interpolate_weekdays_without_cache(year, month)
|
142
163
|
t = Date.new(year, month, 1)
|
143
|
-
valid_mday = time_specs[:dom]
|
144
|
-
valid_wday = time_specs[:dow]
|
164
|
+
valid_mday, _, mday_field = time_specs[:dom]
|
165
|
+
valid_wday, _, wday_field = time_specs[:dow]
|
166
|
+
|
167
|
+
# Careful, if both DOW and DOM fields are non-wildcard,
|
168
|
+
# then we only need to match *one* for cron to run the job:
|
169
|
+
if not (mday_field == '*' and wday_field == '*')
|
170
|
+
valid_mday = [] if mday_field == '*'
|
171
|
+
valid_wday = [] if wday_field == '*'
|
172
|
+
end
|
173
|
+
# Careful: crontabs may use either 0 or 7 for Sunday:
|
174
|
+
valid_wday << 0 if valid_wday.include?(7)
|
145
175
|
|
146
176
|
result = []
|
147
177
|
while t.month == month
|
148
|
-
result << t.mday if valid_mday.include?(t.mday)
|
178
|
+
result << t.mday if valid_mday.include?(t.mday) || valid_wday.include?(t.wday)
|
149
179
|
t = t.succ
|
150
180
|
end
|
151
181
|
|
@@ -211,7 +241,7 @@ class CronParser
|
|
211
241
|
end
|
212
242
|
|
213
243
|
def substitute_parse_symbols(str)
|
214
|
-
SYMBOLS.inject(str) do |s, (symbol, replacement)|
|
244
|
+
SYMBOLS.inject(str.downcase) do |s, (symbol, replacement)|
|
215
245
|
s.gsub(symbol, replacement)
|
216
246
|
end
|
217
247
|
end
|
@@ -237,4 +267,14 @@ class CronParser
|
|
237
267
|
allowed.sort.reverse.find { |val| val < current }
|
238
268
|
end
|
239
269
|
end
|
270
|
+
|
271
|
+
def validate_source
|
272
|
+
unless @source.respond_to?(:split)
|
273
|
+
raise ArgumentError, 'not a valid cronline'
|
274
|
+
end
|
275
|
+
source_length = @source.split(/\s+/).length
|
276
|
+
unless source_length >= 5 && source_length <= 6
|
277
|
+
raise ArgumentError, 'not a valid cronline'
|
278
|
+
end
|
279
|
+
end
|
240
280
|
end
|
data/lib/parse-cron/version.rb
CHANGED
data/spec/cron_parser_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require "time"
|
2
2
|
require "./spec/spec_helper"
|
3
3
|
require "cron_parser"
|
4
|
-
require "
|
4
|
+
require "date"
|
5
5
|
|
6
6
|
def parse_date(str)
|
7
7
|
dt = DateTime.strptime(str, "%Y-%m-%d %H:%M")
|
@@ -10,38 +10,73 @@ end
|
|
10
10
|
|
11
11
|
describe "CronParser#parse_element" do
|
12
12
|
[
|
13
|
-
["*", 0..
|
14
|
-
["*/10", 0..
|
15
|
-
["10", 0..
|
16
|
-
["10,30", 0..
|
17
|
-
["10-15", 0..
|
18
|
-
["10-40/10", 0..
|
13
|
+
["*", 0..59, (0..59).to_a],
|
14
|
+
["*/10", 0..59, [0, 10, 20, 30, 40, 50]],
|
15
|
+
["10", 0..59, [10]],
|
16
|
+
["10,30", 0..59, [10, 30]],
|
17
|
+
["10-15", 0..59, [10, 11, 12, 13, 14, 15]],
|
18
|
+
["10-40/10", 0..59, [10, 20, 30, 40]],
|
19
19
|
].each do |element, range, expected|
|
20
20
|
it "should return #{expected} for '#{element}' when range is #{range}" do
|
21
|
-
parser = CronParser.new('')
|
22
|
-
parser.parse_element(element, range) == expected
|
21
|
+
parser = CronParser.new('* * * * *')
|
22
|
+
parser.parse_element(element, range).first.to_a.sort.should == expected.sort
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
describe "CronParser#next" do
|
28
28
|
[
|
29
|
-
["* * * * *",
|
30
|
-
["* * * * *",
|
31
|
-
["* * * * *",
|
32
|
-
["*/15 * * * *",
|
33
|
-
["*/15,25 * * * *",
|
34
|
-
["30 3,6,9 * * *",
|
35
|
-
["30 9 * * *",
|
36
|
-
["30 9 * * *",
|
37
|
-
["30 9 * * *",
|
38
|
-
["0 9 * * *",
|
39
|
-
["* * 12 * *",
|
40
|
-
["* * * * 1,3",
|
41
|
-
["
|
42
|
-
["0 0
|
43
|
-
["0 0 * * 1",
|
44
|
-
["
|
29
|
+
["* * * * *", "2011-08-15 12:00", "2011-08-15 12:01"],
|
30
|
+
["* * * * *", "2011-08-15 02:25", "2011-08-15 02:26"],
|
31
|
+
["* * * * *", "2011-08-15 02:59", "2011-08-15 03:00"],
|
32
|
+
["*/15 * * * *", "2011-08-15 02:02", "2011-08-15 02:15"],
|
33
|
+
["*/15,25 * * * *", "2011-08-15 02:15", "2011-08-15 02:25"],
|
34
|
+
["30 3,6,9 * * *", "2011-08-15 02:15", "2011-08-15 03:30"],
|
35
|
+
["30 9 * * *", "2011-08-15 10:15", "2011-08-16 09:30"],
|
36
|
+
["30 9 * * *", "2011-08-31 10:15", "2011-09-01 09:30"],
|
37
|
+
["30 9 * * *", "2011-09-30 10:15", "2011-10-01 09:30"],
|
38
|
+
["0 9 * * *", "2011-12-31 10:15", "2012-01-01 09:00"],
|
39
|
+
["* * 12 * *", "2010-04-15 10:15", "2010-05-12 00:00"],
|
40
|
+
["* * * * 1,3", "2010-04-15 10:15", "2010-04-19 00:00"],
|
41
|
+
["* * * * MON,WED", "2010-04-15 10:15", "2010-04-19 00:00"],
|
42
|
+
["0 0 1 1 *", "2010-04-15 10:15", "2011-01-01 00:00"],
|
43
|
+
["0 0 * * 1", "2011-08-01 00:00", "2011-08-08 00:00"],
|
44
|
+
["0 0 * * 1", "2011-07-25 00:00", "2011-08-01 00:00"],
|
45
|
+
["45 23 7 3 *", "2011-01-01 00:00", "2011-03-07 23:45"],
|
46
|
+
["0 0 1 jun *", "2013-05-14 11:20", "2013-06-01 00:00"],
|
47
|
+
["0 0 1 may,jul *", "2013-05-14 15:00", "2013-07-01 00:00"],
|
48
|
+
["0 0 1 MAY,JUL *", "2013-05-14 15:00", "2013-07-01 00:00"],
|
49
|
+
["40 5 * * *", "2014-02-01 15:56", "2014-02-02 05:40"],
|
50
|
+
["0 5 * * 1", "2014-02-01 15:56", "2014-02-03 05:00"],
|
51
|
+
["10 8 15 * *", "2014-02-01 15:56", "2014-02-15 08:10"],
|
52
|
+
["50 6 * * 1", "2014-02-01 15:56", "2014-02-03 06:50"],
|
53
|
+
["1 2 * apr mOn", "2014-02-01 15:56", "2014-04-07 02:01"],
|
54
|
+
["1 2 3 4 7", "2014-02-01 15:56", "2014-04-03 02:01"],
|
55
|
+
["1 2 3 4 7", "2014-04-04 15:56", "2014-04-06 02:01"],
|
56
|
+
["1-20/3 * * * *", "2014-02-01 15:56", "2014-02-01 16:01"],
|
57
|
+
["1,2,3 * * * *", "2014-02-01 15:56", "2014-02-01 16:01"],
|
58
|
+
["1-9,15-30 * * * *", "2014-02-01 15:56", "2014-02-01 16:01"],
|
59
|
+
["1-9/3,15-30/4 * * * *", "2014-02-01 15:56", "2014-02-01 16:01"],
|
60
|
+
["1 2 3 jan mon", "2014-02-01 15:56", "2015-01-03 02:01"],
|
61
|
+
["1 2 3 4 mON", "2014-02-01 15:56", "2014-04-03 02:01"],
|
62
|
+
["1 2 3 jan 5", "2014-02-01 15:56", "2015-01-02 02:01"],
|
63
|
+
["@yearly", "2014-02-01 15:56", "2015-01-01 00:00"],
|
64
|
+
["@annually", "2014-02-01 15:56", "2015-01-01 00:00"],
|
65
|
+
["@monthly", "2014-02-01 15:56", "2014-03-01 00:00"],
|
66
|
+
["@weekly", "2014-02-01 15:56", "2014-02-02 00:00"],
|
67
|
+
["@daily", "2014-02-01 15:56", "2014-02-02 00:00"],
|
68
|
+
["@midnight", "2014-02-01 15:56", "2014-02-02 00:00"],
|
69
|
+
["@hourly", "2014-02-01 15:56", "2014-02-01 16:00"],
|
70
|
+
["*/3 * * * *", "2014-02-01 15:56", "2014-02-01 15:57"],
|
71
|
+
["0 5 * 2,3 *", "2014-02-01 15:56", "2014-02-02 05:00"],
|
72
|
+
["15-59/15 * * * *", "2014-02-01 15:56", "2014-02-01 16:15"],
|
73
|
+
["15-59/15 * * * *", "2014-02-01 15:00", "2014-02-01 15:15"],
|
74
|
+
["15-59/15 * * * *", "2014-02-01 15:01", "2014-02-01 15:15"],
|
75
|
+
["15-59/15 * * * *", "2014-02-01 15:16", "2014-02-01 15:30"],
|
76
|
+
["15-59/15 * * * *", "2014-02-01 15:26", "2014-02-01 15:30"],
|
77
|
+
["15-59/15 * * * *", "2014-02-01 15:36", "2014-02-01 15:45"],
|
78
|
+
["15-59/15 * * * *", "2014-02-01 15:45", "2014-02-01 16:15"],
|
79
|
+
["15-59/15 * * * *", "2014-02-01 15:46", "2014-02-01 16:15"],
|
45
80
|
].each do |line, now, expected_next|
|
46
81
|
it "should return #{expected_next} for '#{line}' when now is #{now}" do
|
47
82
|
now = parse_date(now)
|
@@ -56,20 +91,55 @@ end
|
|
56
91
|
|
57
92
|
describe "CronParser#last" do
|
58
93
|
[
|
59
|
-
["* * * * *",
|
60
|
-
["* * * * *",
|
61
|
-
["* * * * *",
|
62
|
-
["*/15 * * * *",
|
63
|
-
["*/15,45 * * * *",
|
64
|
-
["*/15,25 * * * *",
|
65
|
-
["30 3,6,9 * * *",
|
66
|
-
["30 9 * * *",
|
67
|
-
["30 9 * * *",
|
68
|
-
["30 9 * * *",
|
69
|
-
["0 9 * * *",
|
70
|
-
["* * 12 * *",
|
71
|
-
["* * * * 1,3",
|
72
|
-
["
|
94
|
+
["* * * * *", "2011-08-15 12:00", "2011-08-15 11:59"],
|
95
|
+
["* * * * *", "2011-08-15 02:25", "2011-08-15 02:24"],
|
96
|
+
["* * * * *", "2011-08-15 03:00", "2011-08-15 02:59"],
|
97
|
+
["*/15 * * * *", "2011-08-15 02:02", "2011-08-15 02:00"],
|
98
|
+
["*/15,45 * * * *", "2011-08-15 02:55", "2011-08-15 02:45"],
|
99
|
+
["*/15,25 * * * *", "2011-08-15 02:35", "2011-08-15 02:30"],
|
100
|
+
["30 3,6,9 * * *", "2011-08-15 02:15", "2011-08-14 09:30"],
|
101
|
+
["30 9 * * *", "2011-08-15 10:15", "2011-08-15 09:30"],
|
102
|
+
["30 9 * * *", "2011-09-01 08:15", "2011-08-31 09:30"],
|
103
|
+
["30 9 * * *", "2011-10-01 08:15", "2011-09-30 09:30"],
|
104
|
+
["0 9 * * *", "2012-01-01 00:15", "2011-12-31 09:00"],
|
105
|
+
["* * 12 * *", "2010-04-15 10:15", "2010-04-12 23:59"],
|
106
|
+
["* * * * 1,3", "2010-04-15 10:15", "2010-04-14 23:59"],
|
107
|
+
["* * * * MON,WED", "2010-04-15 10:15", "2010-04-14 23:59"],
|
108
|
+
["0 0 1 1 *", "2010-04-15 10:15", "2010-01-01 00:00"],
|
109
|
+
["0 0 1 jun *", "2013-05-14 11:20", "2012-06-01 00:00"],
|
110
|
+
["0 0 1 may,jul *", "2013-05-14 15:00", "2013-05-01 00:00"],
|
111
|
+
["0 0 1 MAY,JUL *", "2013-05-14 15:00", "2013-05-01 00:00"],
|
112
|
+
["40 5 * * *", "2014-02-01 15:56", "2014-02-01 05:40"],
|
113
|
+
["0 5 * * 1", "2014-02-01 15:56", "2014-01-27 05:00"],
|
114
|
+
["10 8 15 * *", "2014-02-01 15:56", "2014-01-15 08:10"],
|
115
|
+
["50 6 * * 1", "2014-02-01 15:56", "2014-01-27 06:50"],
|
116
|
+
["1 2 * apr mOn", "2014-02-01 15:56", "2013-04-29 02:01"],
|
117
|
+
["1 2 3 4 7", "2014-02-01 15:56", "2013-04-28 02:01"],
|
118
|
+
["1 2 3 4 7", "2014-04-04 15:56", "2014-04-03 02:01"],
|
119
|
+
["1-20/3 * * * *", "2014-02-01 15:56", "2014-02-01 15:19"],
|
120
|
+
["1,2,3 * * * *", "2014-02-01 15:56", "2014-02-01 15:03"],
|
121
|
+
["1-9,15-30 * * * *", "2014-02-01 15:56", "2014-02-01 15:30"],
|
122
|
+
["1-9/3,15-30/4 * * * *", "2014-02-01 15:56", "2014-02-01 15:27"],
|
123
|
+
["1 2 3 jan mon", "2014-02-01 15:56", "2014-01-27 02:01"],
|
124
|
+
["1 2 3 4 mON", "2014-02-01 15:56", "2013-04-29 02:01"],
|
125
|
+
["1 2 3 jan 5", "2014-02-01 15:56", "2014-01-31 02:01"],
|
126
|
+
["@yearly", "2014-02-01 15:56", "2014-01-01 00:00"],
|
127
|
+
["@annually", "2014-02-01 15:56", "2014-01-01 00:00"],
|
128
|
+
["@monthly", "2014-02-01 15:56", "2014-02-01 00:00"],
|
129
|
+
["@weekly", "2014-02-01 15:56", "2014-01-26 00:00"],
|
130
|
+
["@daily", "2014-02-01 15:56", "2014-02-01 00:00"],
|
131
|
+
["@midnight", "2014-02-01 15:56", "2014-02-01 00:00"],
|
132
|
+
["@hourly", "2014-02-01 15:56", "2014-02-01 15:00"],
|
133
|
+
["*/3 * * * *", "2014-02-01 15:56", "2014-02-01 15:54"],
|
134
|
+
["0 5 * 2,3 *", "2014-02-01 15:56", "2014-02-01 05:00"],
|
135
|
+
["15-59/15 * * * *", "2014-02-01 15:56", "2014-02-01 15:45"],
|
136
|
+
["15-59/15 * * * *", "2014-02-01 15:00", "2014-02-01 14:45"],
|
137
|
+
["15-59/15 * * * *", "2014-02-01 15:01", "2014-02-01 14:45"],
|
138
|
+
["15-59/15 * * * *", "2014-02-01 15:16", "2014-02-01 15:15"],
|
139
|
+
["15-59/15 * * * *", "2014-02-01 15:26", "2014-02-01 15:15"],
|
140
|
+
["15-59/15 * * * *", "2014-02-01 15:36", "2014-02-01 15:30"],
|
141
|
+
["15-59/15 * * * *", "2014-02-01 15:45", "2014-02-01 15:30"],
|
142
|
+
["15-59/15 * * * *", "2014-02-01 15:46", "2014-02-01 15:45"],
|
73
143
|
].each do |line, now, expected_next|
|
74
144
|
it "should return #{expected_next} for '#{line}' when now is #{now}" do
|
75
145
|
now = parse_date(now)
|
@@ -82,6 +152,16 @@ describe "CronParser#last" do
|
|
82
152
|
end
|
83
153
|
end
|
84
154
|
|
155
|
+
describe "CronParser#new" do
|
156
|
+
it 'should not raise error when given a valid cronline' do
|
157
|
+
expect { CronParser.new('30 * * * *') }.not_to raise_error
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should raise error when given an invalid cronline' do
|
161
|
+
expect { CronParser.new('* * * *') }.to raise_error('not a valid cronline')
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
85
165
|
describe "time source" do
|
86
166
|
it "should use an alternate specified time source" do
|
87
167
|
ExtendedTime = Class.new(Time)
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parse-cron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Michael Siebert
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-02-06 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rspec
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -36,8 +33,10 @@ extra_rdoc_files: []
|
|
36
33
|
files:
|
37
34
|
- .gitignore
|
38
35
|
- .rspec
|
36
|
+
- .travis.yml
|
39
37
|
- Gemfile
|
40
|
-
-
|
38
|
+
- License
|
39
|
+
- README.md
|
41
40
|
- Rakefile
|
42
41
|
- lib/cron_parser.rb
|
43
42
|
- lib/parse-cron.rb
|
@@ -47,28 +46,25 @@ files:
|
|
47
46
|
- spec/spec_helper.rb
|
48
47
|
homepage: https://github.com/siebertm/parse-cron
|
49
48
|
licenses: []
|
49
|
+
metadata: {}
|
50
50
|
post_install_message:
|
51
51
|
rdoc_options: []
|
52
52
|
require_paths:
|
53
53
|
- lib
|
54
54
|
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
-
none: false
|
56
55
|
requirements:
|
57
56
|
- - ! '>='
|
58
57
|
- !ruby/object:Gem::Version
|
59
58
|
version: '0'
|
60
59
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
-
none: false
|
62
60
|
requirements:
|
63
61
|
- - ! '>='
|
64
62
|
- !ruby/object:Gem::Version
|
65
63
|
version: '0'
|
66
64
|
requirements: []
|
67
65
|
rubyforge_project: parse-cron
|
68
|
-
rubygems_version: 1.
|
66
|
+
rubygems_version: 2.1.11
|
69
67
|
signing_key:
|
70
|
-
specification_version:
|
68
|
+
specification_version: 4
|
71
69
|
summary: Parses cron expressions and calculates the next occurence
|
72
|
-
test_files:
|
73
|
-
- spec/cron_parser_spec.rb
|
74
|
-
- spec/spec_helper.rb
|
70
|
+
test_files: []
|