rufus-scheduler 3.0.7 → 3.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +9 -1
- data/CREDITS.txt +2 -0
- data/README.md +7 -3
- data/TODO.txt +4 -0
- data/lib/rufus/scheduler.rb +12 -7
- data/lib/rufus/scheduler/cronline.rb +18 -2
- data/lib/rufus/scheduler/jobs.rb +6 -3
- data/lib/rufus/scheduler/util.rb +6 -5
- data/rufus-scheduler.gemspec +1 -0
- data/spec/basics_spec.rb +49 -0
- data/spec/cronline_spec.rb +231 -126
- data/spec/custom_locks_spec.rb +2 -2
- data/spec/error_spec.rb +12 -12
- data/spec/job_array_spec.rb +2 -2
- data/spec/job_at_spec.rb +4 -4
- data/spec/job_cron_spec.rb +7 -7
- data/spec/job_every_spec.rb +9 -9
- data/spec/job_interval_spec.rb +5 -5
- data/spec/job_repeat_spec.rb +45 -44
- data/spec/job_spec.rb +67 -67
- data/spec/lockfile_spec.rb +5 -5
- data/spec/parse_spec.rb +120 -78
- data/spec/schedule_at_spec.rb +46 -17
- data/spec/schedule_cron_spec.rb +6 -6
- data/spec/schedule_every_spec.rb +12 -12
- data/spec/schedule_in_spec.rb +8 -8
- data/spec/schedule_interval_spec.rb +13 -13
- data/spec/scheduler_spec.rb +134 -118
- data/spec/spec_helper.rb +50 -1
- data/spec/threads_spec.rb +4 -4
- metadata +20 -9
data/CHANGELOG.txt
CHANGED
@@ -2,13 +2,21 @@
|
|
2
2
|
= rufus-scheduler CHANGELOG.txt
|
3
3
|
|
4
4
|
|
5
|
+
== rufus-scheduler - 3.0.8 released 2014/06/09
|
6
|
+
|
7
|
+
- handle TZInfo errors on DST transitions, thanks https://github.com/junhanamaki
|
8
|
+
- implement Scheduler#up?
|
9
|
+
- let schedule and schedule_at use Chronic if present
|
10
|
+
- let Rufus::Scheduler.parse use Chronic if present
|
11
|
+
|
12
|
+
|
5
13
|
== rufus-scheduler - 3.0.7 released 2014/03/18
|
6
14
|
|
7
15
|
- implement Scheduler #occurrences and #timeline, inspired by kreynolds
|
8
16
|
- implement Job #last_work_time and #mean_work_time
|
9
17
|
- implement Job#count
|
10
18
|
- add more info to the stderr error output (scheduler/tz info)
|
11
|
-
- prevent skipping a day on
|
19
|
+
- prevent skipping a day on switch to summertime, gh-114, thanks Matteo
|
12
20
|
|
13
21
|
|
14
22
|
== rufus-scheduler - 3.0.6 released 2014/02/14
|
data/CREDITS.txt
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
|
5
5
|
== Contributors
|
6
6
|
|
7
|
+
- Adam Jonas (https://github.com/adamjonas) migrate specs to "expect"
|
7
8
|
- Yassen Bantchev (https://github.com/yassenb) CronLine#previous_time rewrite
|
8
9
|
- Eric Lindvall (https://github.com/eric) Zookeeper locked example
|
9
10
|
- Ted Pennings (https://github.com/tedpennings) typo in post_install_message
|
@@ -30,6 +31,7 @@
|
|
30
31
|
|
31
32
|
== Feedback
|
32
33
|
|
34
|
+
- junhanamaki - https://github.com/junhanamaki - #next_time and dst ambiguities
|
33
35
|
- kreynolds (tossrock) - inspiration for #occurrences
|
34
36
|
- Matteo - https://github.com/m4ce - dst and cron issue
|
35
37
|
- Tobias Bielohlawek - https://github.com/rngtng - missing assertion
|
data/README.md
CHANGED
@@ -394,8 +394,8 @@ This option is for repeat jobs (cron / every) only.
|
|
394
394
|
|
395
395
|
It's used to specify the first time after which the repeat job should trigger for the first time.
|
396
396
|
|
397
|
-
In the case of an "every" job, this will be the first time (
|
398
|
-
For a "cron" job, it's the time after which the first schedule will trigger.
|
397
|
+
In the case of an "every" job, this will be the first time (modulo the scheduler frequency) the job triggers.
|
398
|
+
For a "cron" job, it's the time *after* which the first schedule will trigger.
|
399
399
|
|
400
400
|
```ruby
|
401
401
|
scheduler.every '2d', :first_at => Time.now + 10 * 3600 do
|
@@ -405,6 +405,10 @@ end
|
|
405
405
|
scheduler.every '2d', :first_in => '10h' do
|
406
406
|
# ... every two days, but start in 10 hours
|
407
407
|
end
|
408
|
+
|
409
|
+
scheduler.cron '00 14 * * *', :first_in => '3d' do
|
410
|
+
# ... every day at 14h00, but start after 3 * 24 hours
|
411
|
+
end
|
408
412
|
```
|
409
413
|
|
410
414
|
:first, :first_at and :first_in all accept a point in time or a duration (number or time string). Use the symbol you think make your schedule more readable.
|
@@ -1135,7 +1139,7 @@ Rufus::Scheduler.s.every '10s' { puts "hello, world!" }
|
|
1135
1139
|
|
1136
1140
|
## advanced lock schemes
|
1137
1141
|
|
1138
|
-
As seen above, rufus-scheduler proposes the :lockfile system out of the box. If in a group of schedulers only one is supposed to run, the lockfile mecha prevents schedulers that have not set/created the lockfile from running.
|
1142
|
+
As seen above, rufus-scheduler proposes the [:lockfile](#lockfile--mylockfiletxt) system out of the box. If in a group of schedulers only one is supposed to run, the lockfile mecha prevents schedulers that have not set/created the lockfile from running.
|
1139
1143
|
|
1140
1144
|
There are situation where this is not sufficient.
|
1141
1145
|
|
data/TODO.txt
CHANGED
data/lib/rufus/scheduler.rb
CHANGED
@@ -38,7 +38,7 @@ module Rufus
|
|
38
38
|
require 'rufus/scheduler/cronline'
|
39
39
|
require 'rufus/scheduler/job_array'
|
40
40
|
|
41
|
-
VERSION = '3.0.
|
41
|
+
VERSION = '3.0.8'
|
42
42
|
|
43
43
|
#
|
44
44
|
# A common error class for rufus-scheduler
|
@@ -165,6 +165,11 @@ module Rufus
|
|
165
165
|
! @started_at
|
166
166
|
end
|
167
167
|
|
168
|
+
def up?
|
169
|
+
|
170
|
+
!! @started_at
|
171
|
+
end
|
172
|
+
|
168
173
|
def paused?
|
169
174
|
|
170
175
|
@paused
|
@@ -236,9 +241,9 @@ module Rufus
|
|
236
241
|
|
237
242
|
def schedule(arg, callable=nil, opts={}, &block)
|
238
243
|
|
239
|
-
|
244
|
+
opts[:_t] = Scheduler.parse(arg, opts)
|
240
245
|
|
241
|
-
case
|
246
|
+
case opts[:_t]
|
242
247
|
when CronLine then schedule_cron(arg, callable, opts, &block)
|
243
248
|
when Time then schedule_at(arg, callable, opts, &block)
|
244
249
|
else schedule_in(arg, callable, opts, &block)
|
@@ -247,9 +252,9 @@ module Rufus
|
|
247
252
|
|
248
253
|
def repeat(arg, callable=nil, opts={}, &block)
|
249
254
|
|
250
|
-
|
255
|
+
opts[:_t] = Scheduler.parse(arg, opts)
|
251
256
|
|
252
|
-
case
|
257
|
+
case opts[:_t]
|
253
258
|
when CronLine then schedule_cron(arg, callable, opts, &block)
|
254
259
|
else schedule_every(arg, callable, opts, &block)
|
255
260
|
end
|
@@ -612,8 +617,8 @@ module Rufus
|
|
612
617
|
job_class =
|
613
618
|
case job_type
|
614
619
|
when :once
|
615
|
-
|
616
|
-
|
620
|
+
opts[:_t] ||= Rufus::Scheduler.parse(t, opts)
|
621
|
+
opts[:_t].is_a?(Time) ? AtJob : InJob
|
617
622
|
when :every
|
618
623
|
EveryJob
|
619
624
|
when :interval
|
@@ -149,6 +149,10 @@ class Rufus::Scheduler
|
|
149
149
|
end
|
150
150
|
|
151
151
|
global_time(time, from.utc?)
|
152
|
+
|
153
|
+
rescue TZInfo::PeriodNotFound
|
154
|
+
|
155
|
+
next_time(from + 3600)
|
152
156
|
end
|
153
157
|
|
154
158
|
# Returns the previous time the cronline matched. It's like next_time, but
|
@@ -180,6 +184,10 @@ class Rufus::Scheduler
|
|
180
184
|
end
|
181
185
|
|
182
186
|
global_time(time, from.utc?)
|
187
|
+
|
188
|
+
rescue TZInfo::PeriodNotFound
|
189
|
+
|
190
|
+
previous_time(time)
|
183
191
|
end
|
184
192
|
|
185
193
|
# Returns an array of 6 arrays (seconds, minutes, hours, days,
|
@@ -429,12 +437,19 @@ class Rufus::Scheduler
|
|
429
437
|
end
|
430
438
|
|
431
439
|
def local_time(time)
|
432
|
-
|
440
|
+
|
441
|
+
@timezone ? @timezone.utc_to_local(time.getutc) : time
|
433
442
|
end
|
434
443
|
|
435
444
|
def global_time(time, from_in_utc)
|
445
|
+
|
436
446
|
if @timezone
|
437
|
-
time =
|
447
|
+
time =
|
448
|
+
begin
|
449
|
+
@timezone.local_to_utc(time)
|
450
|
+
rescue TZInfo::AmbiguousTime
|
451
|
+
@timezone.local_to_utc(time, time.isdst)
|
452
|
+
end
|
438
453
|
time = time.getlocal unless from_in_utc
|
439
454
|
end
|
440
455
|
|
@@ -442,6 +457,7 @@ class Rufus::Scheduler
|
|
442
457
|
end
|
443
458
|
|
444
459
|
def round_to_seconds(time)
|
460
|
+
|
445
461
|
# Ruby 1.8 doesn't have #round
|
446
462
|
time.respond_to?(:round) ? time.round : time - time.usec * 1e-6
|
447
463
|
end
|
data/lib/rufus/scheduler/jobs.rb
CHANGED
@@ -368,7 +368,8 @@ module Rufus
|
|
368
368
|
|
369
369
|
super(scheduler, time, opts, block)
|
370
370
|
|
371
|
-
@next_time =
|
371
|
+
@next_time =
|
372
|
+
opts[:_t] || Rufus::Scheduler.parse_at(time, opts)
|
372
373
|
end
|
373
374
|
end
|
374
375
|
|
@@ -378,7 +379,9 @@ module Rufus
|
|
378
379
|
|
379
380
|
super(scheduler, duration, opts, block)
|
380
381
|
|
381
|
-
@next_time =
|
382
|
+
@next_time =
|
383
|
+
@scheduled_at +
|
384
|
+
opts[:_t] || Rufus::Scheduler.parse_in(duration, opts)
|
382
385
|
end
|
383
386
|
end
|
384
387
|
|
@@ -597,7 +600,7 @@ module Rufus
|
|
597
600
|
|
598
601
|
super(scheduler, cronline, opts, block)
|
599
602
|
|
600
|
-
@cron_line = CronLine.new(cronline)
|
603
|
+
@cron_line = opts[:_t] || CronLine.new(cronline)
|
601
604
|
@next_time = @cron_line.next_time
|
602
605
|
end
|
603
606
|
|
data/lib/rufus/scheduler/util.rb
CHANGED
@@ -31,9 +31,9 @@ module Rufus
|
|
31
31
|
# time and string methods
|
32
32
|
#++
|
33
33
|
|
34
|
-
def self.parse(o)
|
34
|
+
def self.parse(o, opts={})
|
35
35
|
|
36
|
-
opts
|
36
|
+
opts[:no_error] = true
|
37
37
|
|
38
38
|
parse_cron(o, opts) ||
|
39
39
|
parse_in(o, opts) || # covers 'every' schedule strings
|
@@ -52,6 +52,9 @@ module Rufus
|
|
52
52
|
|
53
53
|
return o if o.is_a?(Time)
|
54
54
|
|
55
|
+
# TODO: deal with tz if suffixed to Chronic string?
|
56
|
+
return Chronic.parse(o, opts) if defined?(Chronic)
|
57
|
+
|
55
58
|
tz = nil
|
56
59
|
s =
|
57
60
|
o.to_s.gsub(TZ_REGEX) { |m|
|
@@ -68,9 +71,7 @@ module Rufus
|
|
68
71
|
|
69
72
|
t = Time.parse(s)
|
70
73
|
|
71
|
-
|
72
|
-
|
73
|
-
t
|
74
|
+
tz ? tz.local_to_utc(t) : t
|
74
75
|
|
75
76
|
rescue StandardError => se
|
76
77
|
|
data/rufus-scheduler.gemspec
CHANGED
data/spec/basics_spec.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Specifying rufus-scheduler
|
4
|
+
#
|
5
|
+
# Sun Jun 1 05:52:24 JST 2014
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'spec_helper'
|
9
|
+
|
10
|
+
|
11
|
+
describe 'basics' do
|
12
|
+
|
13
|
+
def tts(time)
|
14
|
+
|
15
|
+
time.strftime('%Y-%m-%d %H:%M:%S %z') + (time.dst? ? ' dst' : '')
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'Time.new' do
|
19
|
+
|
20
|
+
it 'accepts a timezone final argument' do
|
21
|
+
|
22
|
+
pending if jruby? or ruby18?
|
23
|
+
|
24
|
+
expect(
|
25
|
+
tts(Time.new(2014, 1, 1, 1, 0, 0, '+01:00'))
|
26
|
+
).to eq('2014-01-01 01:00:00 +0100')
|
27
|
+
expect(
|
28
|
+
tts(Time.new(2014, 8, 1, 1, 0, 0, '+01:00'))
|
29
|
+
).to eq('2014-08-01 01:00:00 +0100')
|
30
|
+
expect(
|
31
|
+
tts(Time.new(2014, 8, 1, 1, 0, 0, '+01:00'))
|
32
|
+
).to eq('2014-08-01 01:00:00 +0100')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'Time.local' do
|
37
|
+
|
38
|
+
it 'works as expected' do
|
39
|
+
|
40
|
+
expect(
|
41
|
+
tts(in_zone('Europe/Berlin') { Time.local(2014, 1, 1, 1, 0, 0) })
|
42
|
+
).to eq('2014-01-01 01:00:00 +0100')
|
43
|
+
expect(
|
44
|
+
tts(in_zone('Europe/Berlin') { Time.local(2014, 8, 1, 1, 0, 0) })
|
45
|
+
).to eq('2014-08-01 01:00:00 +0200 dst')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
data/spec/cronline_spec.rb
CHANGED
@@ -16,13 +16,13 @@ describe Rufus::Scheduler::CronLine do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def match(line, time)
|
19
|
-
cl(line).matches?(time).
|
19
|
+
expect(cl(line).matches?(time)).to eq(true)
|
20
20
|
end
|
21
21
|
def no_match(line, time)
|
22
|
-
cl(line).matches?(time).
|
22
|
+
expect(cl(line).matches?(time)).to eq(false)
|
23
23
|
end
|
24
24
|
def to_a(line, array)
|
25
|
-
cl(line).to_array.
|
25
|
+
expect(cl(line).to_array).to eq(array)
|
26
26
|
end
|
27
27
|
|
28
28
|
describe '.new' do
|
@@ -59,17 +59,17 @@ describe Rufus::Scheduler::CronLine do
|
|
59
59
|
|
60
60
|
it 'rejects invalid weekday expressions' do
|
61
61
|
|
62
|
-
|
62
|
+
expect { cl '0 17 * * MON_FRI' }.to raise_error
|
63
63
|
# underline instead of dash
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
expect { cl '* * * * 9' }.to raise_error
|
66
|
+
expect { cl '* * * * 0-12' }.to raise_error
|
67
|
+
expect { cl '* * * * BLABLA' }.to raise_error
|
68
68
|
end
|
69
69
|
|
70
70
|
it 'rejects invalid cronlines' do
|
71
71
|
|
72
|
-
|
72
|
+
expect { cl '* nada * * 9' }.to raise_error(ArgumentError)
|
73
73
|
end
|
74
74
|
|
75
75
|
it 'interprets cron strings with TZ correctly' do
|
@@ -84,8 +84,8 @@ describe Rufus::Scheduler::CronLine do
|
|
84
84
|
'* * * * * * America/New_York',
|
85
85
|
[ nil, nil, nil, nil, nil, nil, nil, 'America/New_York' ])
|
86
86
|
|
87
|
-
|
88
|
-
|
87
|
+
expect { cl '* * * * * NotATimeZone' }.to raise_error
|
88
|
+
expect { cl '* * * * * * NotATimeZone' }.to raise_error
|
89
89
|
end
|
90
90
|
|
91
91
|
it 'interprets cron strings with / (slashes) correctly' do
|
@@ -118,59 +118,69 @@ describe Rufus::Scheduler::CronLine do
|
|
118
118
|
|
119
119
|
it 'rejects / for days (every other wednesday)' do
|
120
120
|
|
121
|
-
|
121
|
+
expect {
|
122
122
|
Rufus::Scheduler::CronLine.new('* * * * wed/2')
|
123
|
-
}.
|
123
|
+
}.to raise_error(ArgumentError)
|
124
124
|
end
|
125
125
|
|
126
126
|
it 'does not support ranges for monthdays (sun#1-sun#2)' do
|
127
127
|
|
128
|
-
|
128
|
+
expect {
|
129
129
|
Rufus::Scheduler::CronLine.new('* * * * sun#1-sun#2')
|
130
|
-
}.
|
130
|
+
}.to raise_error(ArgumentError)
|
131
131
|
end
|
132
132
|
|
133
133
|
it 'accepts items with initial 0' do
|
134
134
|
|
135
|
-
to_a
|
136
|
-
|
137
|
-
to_a
|
138
|
-
|
139
|
-
to_a
|
140
|
-
|
141
|
-
to_a
|
135
|
+
to_a(
|
136
|
+
'09 * * * *', [ [0], [9], nil, nil, nil, nil, nil, nil ])
|
137
|
+
to_a(
|
138
|
+
'09-12 * * * *', [ [0], [9, 10, 11, 12], nil, nil, nil, nil, nil, nil ])
|
139
|
+
to_a(
|
140
|
+
'07-08 * * * *', [ [0], [7, 8], nil, nil, nil, nil, nil, nil ])
|
141
|
+
to_a(
|
142
|
+
'* */08 * * *', [ [0], nil, [0, 8, 16], nil, nil, nil, nil, nil ])
|
143
|
+
to_a(
|
144
|
+
'* */07 * * *', [ [0], nil, [0, 7, 14, 21], nil, nil, nil, nil, nil ])
|
145
|
+
to_a(
|
146
|
+
'* 01-09/04 * * *', [ [0], nil, [1, 5, 9], nil, nil, nil, nil, nil ])
|
147
|
+
to_a(
|
148
|
+
'* * * * 06', [ [0], nil, nil, nil, nil, [6], nil, nil ])
|
142
149
|
end
|
143
150
|
|
144
151
|
it 'interprets cron strings with L correctly' do
|
145
152
|
|
146
|
-
to_a
|
147
|
-
|
148
|
-
to_a
|
153
|
+
to_a(
|
154
|
+
'* * L * *', [[0], nil, nil, ['L'], nil, nil, nil, nil ])
|
155
|
+
to_a(
|
156
|
+
'* * 2-5,L * *', [[0], nil, nil, [2,3,4,5,'L'], nil, nil, nil, nil ])
|
157
|
+
to_a(
|
158
|
+
'* * */8,L * *', [[0], nil, nil, [1,9,17,25,'L'], nil, nil, nil, nil ])
|
149
159
|
end
|
150
160
|
|
151
161
|
it 'does not support ranges for L' do
|
152
162
|
|
153
|
-
|
154
|
-
|
163
|
+
expect { cl '* * 15-L * *'}.to raise_error(ArgumentError)
|
164
|
+
expect { cl '* * L/4 * *'}.to raise_error(ArgumentError)
|
155
165
|
end
|
156
166
|
|
157
167
|
it 'does not support multiple Ls' do
|
158
168
|
|
159
|
-
|
169
|
+
expect { cl '* * L,L * *'}.to raise_error(ArgumentError)
|
160
170
|
end
|
161
171
|
|
162
172
|
it 'raises if L is used for something else than days' do
|
163
173
|
|
164
|
-
|
174
|
+
expect { cl '* L * * *'}.to raise_error(ArgumentError)
|
165
175
|
end
|
166
176
|
|
167
177
|
it 'raises for out of range input' do
|
168
178
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
179
|
+
expect { cl '60-62 * * * *'}.to raise_error(ArgumentError)
|
180
|
+
expect { cl '62 * * * *'}.to raise_error(ArgumentError)
|
181
|
+
expect { cl '60 * * * *'}.to raise_error(ArgumentError)
|
182
|
+
expect { cl '* 25-26 * * *'}.to raise_error(ArgumentError)
|
183
|
+
expect { cl '* 25 * * *'}.to raise_error(ArgumentError)
|
174
184
|
#
|
175
185
|
# as reported by Aimee Rose in
|
176
186
|
# https://github.com/jmettraux/rufus-scheduler/pull/58
|
@@ -182,64 +192,69 @@ describe Rufus::Scheduler::CronLine do
|
|
182
192
|
def nt(cronline, now)
|
183
193
|
Rufus::Scheduler::CronLine.new(cronline).next_time(now)
|
184
194
|
end
|
195
|
+
def ntz(cronline, now)
|
196
|
+
tz = cronline.split.last
|
197
|
+
tu = nt(cronline, now).utc
|
198
|
+
in_zone(tz) { tu.getlocal }
|
199
|
+
end
|
185
200
|
|
186
201
|
it 'computes the next occurence correctly' do
|
187
202
|
|
188
203
|
now = Time.at(0).getutc # Thu Jan 01 00:00:00 UTC 1970
|
189
204
|
|
190
|
-
nt('* * * * *', now).
|
191
|
-
nt('* * * * sun', now).
|
192
|
-
nt('* * * * * *', now).
|
193
|
-
nt('* * 13 * fri', now).
|
205
|
+
expect(nt('* * * * *', now)).to eq(now + 60)
|
206
|
+
expect(nt('* * * * sun', now)).to eq(now + 259200)
|
207
|
+
expect(nt('* * * * * *', now)).to eq(now + 1)
|
208
|
+
expect(nt('* * 13 * fri', now)).to eq(now + 3715200)
|
194
209
|
|
195
|
-
nt('10 12 13 12 *', now).
|
210
|
+
expect(nt('10 12 13 12 *', now)).to eq(now + 29938200)
|
196
211
|
# this one is slow (1 year == 3 seconds)
|
197
212
|
#
|
198
213
|
# historical note:
|
199
214
|
# (comment made in 2006 or 2007, the underlying libs got better and
|
200
215
|
# that slowness is gone)
|
201
216
|
|
202
|
-
nt('0 0 * * thu', now).
|
203
|
-
nt('00 0 * * thu', now).
|
217
|
+
expect(nt('0 0 * * thu', now)).to eq(now + 604800)
|
218
|
+
expect(nt('00 0 * * thu', now)).to eq(now + 604800)
|
204
219
|
|
205
|
-
nt('0 0 * * *', now).
|
206
|
-
nt('0 24 * * *', now).
|
220
|
+
expect(nt('0 0 * * *', now)).to eq(now + 24 * 3600)
|
221
|
+
expect(nt('0 24 * * *', now)).to eq(now + 24 * 3600)
|
207
222
|
|
208
223
|
now = local(2008, 12, 31, 23, 59, 59, 0)
|
209
224
|
|
210
|
-
nt('* * * * *', now).
|
225
|
+
expect(nt('* * * * *', now)).to eq(now + 1)
|
211
226
|
end
|
212
227
|
|
213
228
|
it 'computes the next occurence correctly in UTC (TZ not specified)' do
|
214
229
|
|
215
230
|
now = utc(1970, 1, 1)
|
216
231
|
|
217
|
-
nt('* * * * *', now).
|
218
|
-
nt('* * * * sun', now).
|
219
|
-
nt('* * * * * *', now).
|
220
|
-
nt('* * 13 * fri', now).
|
232
|
+
expect(nt('* * * * *', now)).to eq(utc(1970, 1, 1, 0, 1))
|
233
|
+
expect(nt('* * * * sun', now)).to eq(utc(1970, 1, 4))
|
234
|
+
expect(nt('* * * * * *', now)).to eq(utc(1970, 1, 1, 0, 0, 1))
|
235
|
+
expect(nt('* * 13 * fri', now)).to eq(utc(1970, 2, 13))
|
221
236
|
|
222
|
-
nt('10 12 13 12 *', now).
|
237
|
+
expect(nt('10 12 13 12 *', now)).to eq(utc(1970, 12, 13, 12, 10))
|
223
238
|
# this one is slow (1 year == 3 seconds)
|
224
|
-
nt('* * 1 6 *', now).
|
239
|
+
expect(nt('* * 1 6 *', now)).to eq(utc(1970, 6, 1))
|
225
240
|
|
226
|
-
nt('0 0 * * thu', now).
|
241
|
+
expect(nt('0 0 * * thu', now)).to eq(utc(1970, 1, 8))
|
227
242
|
end
|
228
243
|
|
229
244
|
it 'computes the next occurence correctly in local TZ (TZ not specified)' do
|
230
245
|
|
231
246
|
now = local(1970, 1, 1)
|
232
247
|
|
233
|
-
nt('* * * * *', now).
|
234
|
-
nt('* * * * sun', now).
|
235
|
-
nt('* * * * * *', now).
|
236
|
-
nt('* * 13 * fri', now).
|
248
|
+
expect(nt('* * * * *', now)).to eq(local(1970, 1, 1, 0, 1))
|
249
|
+
expect(nt('* * * * sun', now)).to eq(local(1970, 1, 4))
|
250
|
+
expect(nt('* * * * * *', now)).to eq(local(1970, 1, 1, 0, 0, 1))
|
251
|
+
expect(nt('* * 13 * fri', now)).to eq(local(1970, 2, 13))
|
237
252
|
|
238
|
-
nt('10 12 13 12 *', now).
|
253
|
+
expect(nt('10 12 13 12 *', now)).to eq(local(1970, 12, 13, 12, 10))
|
239
254
|
# this one is slow (1 year == 3 seconds)
|
240
|
-
nt('* * 1 6 *', now).
|
255
|
+
expect(nt('* * 1 6 *', now)).to eq(local(1970, 6, 1))
|
241
256
|
|
242
|
-
nt('0 0 * * thu', now).
|
257
|
+
expect(nt('0 0 * * thu', now)).to eq(local(1970, 1, 8))
|
243
258
|
end
|
244
259
|
|
245
260
|
it 'computes the next occurence correctly in UTC (TZ specified)' do
|
@@ -249,15 +264,15 @@ describe Rufus::Scheduler::CronLine do
|
|
249
264
|
now = tz.local_to_utc(local(1970, 1, 1))
|
250
265
|
# Midnight in zone, UTC
|
251
266
|
|
252
|
-
nt("* * * * * #{zone}", now).
|
253
|
-
nt("* * * * sun #{zone}", now).
|
254
|
-
nt("* * * * * * #{zone}", now).
|
255
|
-
nt("* * 13 * fri #{zone}", now).
|
267
|
+
expect(nt("* * * * * #{zone}", now)).to eq(utc(1969, 12, 31, 23, 1))
|
268
|
+
expect(nt("* * * * sun #{zone}", now)).to eq(utc(1970, 1, 3, 23))
|
269
|
+
expect(nt("* * * * * * #{zone}", now)).to eq(utc(1969, 12, 31, 23, 0, 1))
|
270
|
+
expect(nt("* * 13 * fri #{zone}", now)).to eq(utc(1970, 2, 12, 23))
|
256
271
|
|
257
|
-
nt("10 12 13 12 * #{zone}", now).
|
258
|
-
nt("* * 1 6 * #{zone}", now).
|
272
|
+
expect(nt("10 12 13 12 * #{zone}", now)).to eq(utc(1970, 12, 13, 11, 10))
|
273
|
+
expect(nt("* * 1 6 * #{zone}", now)).to eq(utc(1970, 5, 31, 23))
|
259
274
|
|
260
|
-
nt("0 0 * * thu #{zone}", now).
|
275
|
+
expect(nt("0 0 * * thu #{zone}", now)).to eq(utc(1970, 1, 7, 23))
|
261
276
|
end
|
262
277
|
|
263
278
|
#it 'computes the next occurence correctly in local TZ (TZ specified)' do
|
@@ -276,45 +291,85 @@ describe Rufus::Scheduler::CronLine do
|
|
276
291
|
|
277
292
|
it 'computes the next time correctly when there is a sun#2 involved' do
|
278
293
|
|
279
|
-
nt('* * * * sun#1', local(1970, 1, 1)).
|
280
|
-
nt('* * * * sun#2', local(1970, 1, 1)).
|
294
|
+
expect(nt('* * * * sun#1', local(1970, 1, 1))).to eq(local(1970, 1, 4))
|
295
|
+
expect(nt('* * * * sun#2', local(1970, 1, 1))).to eq(local(1970, 1, 11))
|
281
296
|
|
282
|
-
nt('* * * * sun#2', local(1970, 1, 12)).
|
297
|
+
expect(nt('* * * * sun#2', local(1970, 1, 12))).to eq(local(1970, 2, 8))
|
283
298
|
end
|
284
299
|
|
285
|
-
it 'computes
|
300
|
+
it 'computes next time correctly when there is a sun#2,sun#3 involved' do
|
286
301
|
|
287
|
-
|
288
|
-
|
302
|
+
expect(
|
303
|
+
nt('* * * * sun#2,sun#3', local(1970, 1, 1))).to eq(local(1970, 1, 11))
|
304
|
+
expect(
|
305
|
+
nt('* * * * sun#2,sun#3', local(1970, 1, 12))).to eq(local(1970, 1, 18))
|
289
306
|
end
|
290
307
|
|
291
308
|
it 'understands sun#L' do
|
292
309
|
|
293
|
-
nt('* * * * sun#L', local(1970, 1, 1)).
|
310
|
+
expect(nt('* * * * sun#L', local(1970, 1, 1))).to eq(local(1970, 1, 25))
|
294
311
|
end
|
295
312
|
|
296
313
|
it 'understands sun#-1' do
|
297
314
|
|
298
|
-
nt('* * * * sun#-1', local(1970, 1, 1)).
|
315
|
+
expect(nt('* * * * sun#-1', local(1970, 1, 1))).to eq(local(1970, 1, 25))
|
299
316
|
end
|
300
317
|
|
301
318
|
it 'understands sun#-2' do
|
302
319
|
|
303
|
-
nt('* * * * sun#-2', local(1970, 1, 1)).
|
320
|
+
expect(nt('* * * * sun#-2', local(1970, 1, 1))).to eq(local(1970, 1, 18))
|
304
321
|
end
|
305
322
|
|
306
323
|
it 'computes the next time correctly when "L" (last day of month)' do
|
307
324
|
|
308
|
-
nt('* * L * *', lo(1970, 1, 1)).
|
309
|
-
nt('* * L * *', lo(1970, 2, 1)).
|
310
|
-
nt('* * L * *', lo(1972, 2, 1)).
|
311
|
-
nt('* * L * *', lo(1970, 4, 1)).
|
325
|
+
expect(nt('* * L * *', lo(1970, 1, 1))).to eq(lo(1970, 1, 31))
|
326
|
+
expect(nt('* * L * *', lo(1970, 2, 1))).to eq(lo(1970, 2, 28))
|
327
|
+
expect(nt('* * L * *', lo(1972, 2, 1))).to eq(lo(1972, 2, 29))
|
328
|
+
expect(nt('* * L * *', lo(1970, 4, 1))).to eq(lo(1970, 4, 30))
|
312
329
|
end
|
313
330
|
|
314
331
|
it 'returns a time with subseconds chopped off' do
|
315
332
|
|
316
|
-
|
317
|
-
|
333
|
+
expect(
|
334
|
+
nt('* * * * *', Time.now).usec).to eq(0)
|
335
|
+
expect(
|
336
|
+
nt('* * * * *', Time.now).iso8601(10).match(/\.0+[^\d]/)).not_to eq(nil)
|
337
|
+
end
|
338
|
+
|
339
|
+
# New York EST: UTC-5
|
340
|
+
# summer (dst) EDT: UTC-4
|
341
|
+
|
342
|
+
# gh-127
|
343
|
+
#
|
344
|
+
it 'survives TZInfo::AmbiguousTime' do
|
345
|
+
|
346
|
+
if ruby18? or jruby?
|
347
|
+
expect(
|
348
|
+
ntz(
|
349
|
+
'30 1 31 10 * America/New_York',
|
350
|
+
ltz('America/New_York', 2004, 10, 1)
|
351
|
+
).strftime('%Y-%m-%d %H:%M:%S')
|
352
|
+
).to eq('2004-10-31 01:30:00')
|
353
|
+
else
|
354
|
+
expect(
|
355
|
+
ntz(
|
356
|
+
'30 1 31 10 * America/New_York',
|
357
|
+
ltz('America/New_York', 2004, 10, 1)
|
358
|
+
)
|
359
|
+
).to eq(ltz('America/New_York', 2004, 10, 31, 1, 30, 0))
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
# gh-127
|
364
|
+
#
|
365
|
+
it 'survives TZInfo::PeriodNotFound' do
|
366
|
+
|
367
|
+
expect(
|
368
|
+
ntz(
|
369
|
+
'0 2 9 3 * America/New_York',
|
370
|
+
ltz('America/New_York', 2014, 3, 1)
|
371
|
+
)
|
372
|
+
).to eq(ltz('America/New_York', 2015, 3, 9, 2, 0, 0))
|
318
373
|
end
|
319
374
|
end
|
320
375
|
|
@@ -323,15 +378,61 @@ describe Rufus::Scheduler::CronLine do
|
|
323
378
|
def pt(cronline, now)
|
324
379
|
Rufus::Scheduler::CronLine.new(cronline).previous_time(now)
|
325
380
|
end
|
381
|
+
def ptz(cronline, now)
|
382
|
+
tz = cronline.split.last
|
383
|
+
tu = pt(cronline, now).utc
|
384
|
+
in_zone(tz) { tu.getlocal }
|
385
|
+
end
|
326
386
|
|
327
387
|
it 'returns the previous time the cron should have triggered' do
|
328
388
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
389
|
+
expect(
|
390
|
+
pt('* * * * sun', lo(1970, 1, 1))).to eq(lo(1969, 12, 28, 23, 59, 00))
|
391
|
+
expect(
|
392
|
+
pt('* * 13 * *', lo(1970, 1, 1))).to eq(lo(1969, 12, 13, 23, 59, 00))
|
393
|
+
expect(
|
394
|
+
pt('0 12 13 * *', lo(1970, 1, 1))).to eq(lo(1969, 12, 13, 12, 00))
|
395
|
+
expect(
|
396
|
+
pt('0 0 2 1 *', lo(1970, 1, 1))).to eq(lo(1969, 1, 2, 0, 00))
|
397
|
+
|
398
|
+
expect(
|
399
|
+
pt('* * * * * sun', lo(1970, 1, 1))).to eq(lo(1969, 12, 28, 23, 59, 59))
|
400
|
+
end
|
401
|
+
|
402
|
+
# New York EST: UTC-5
|
403
|
+
# summer (dst) EDT: UTC-4
|
404
|
+
|
405
|
+
# gh-127
|
406
|
+
#
|
407
|
+
it 'survives TZInfo::AmbiguousTime' do
|
408
|
+
|
409
|
+
if ruby18? or jruby?
|
410
|
+
expect(
|
411
|
+
ptz(
|
412
|
+
'30 1 31 10 * America/New_York',
|
413
|
+
ltz('America/New_York', 2004, 10, 31, 14, 30, 0)
|
414
|
+
).strftime('%Y-%m-%d %H:%M:%S')
|
415
|
+
).to eq('2004-10-31 01:30:00')
|
416
|
+
else
|
417
|
+
expect(
|
418
|
+
ptz(
|
419
|
+
'30 1 31 10 * America/New_York',
|
420
|
+
ltz('America/New_York', 2004, 10, 31, 14, 30, 0)
|
421
|
+
)
|
422
|
+
).to eq(ltz('America/New_York', 2004, 10, 31, 1, 30, 0))
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
# gh-127
|
427
|
+
#
|
428
|
+
it 'survives TZInfo::PeriodNotFound' do
|
333
429
|
|
334
|
-
|
430
|
+
expect(
|
431
|
+
ptz(
|
432
|
+
'0 2 9 3 * America/New_York',
|
433
|
+
ltz('America/New_York', 2015, 3, 9, 12, 0, 0)
|
434
|
+
)
|
435
|
+
).to eq(ltz('America/New_York', 2015, 3, 9, 2, 0, 0))
|
335
436
|
end
|
336
437
|
end
|
337
438
|
|
@@ -432,11 +533,11 @@ describe Rufus::Scheduler::CronLine do
|
|
432
533
|
|
433
534
|
cl = Rufus::Scheduler::CronLine.new('* * * * *')
|
434
535
|
|
435
|
-
cl.monthdays(local(1970, 1, 1)).
|
436
|
-
cl.monthdays(local(1970, 1, 7)).
|
437
|
-
cl.monthdays(local(1970, 1, 14)).
|
536
|
+
expect(cl.monthdays(local(1970, 1, 1))).to eq(%w[ thu#1 thu#-5 ])
|
537
|
+
expect(cl.monthdays(local(1970, 1, 7))).to eq(%w[ wed#1 wed#-4 ])
|
538
|
+
expect(cl.monthdays(local(1970, 1, 14))).to eq(%w[ wed#2 wed#-3 ])
|
438
539
|
|
439
|
-
cl.monthdays(local(2011, 3, 11)).
|
540
|
+
expect(cl.monthdays(local(2011, 3, 11))).to eq(%w[ fri#2 fri#-3 ])
|
440
541
|
end
|
441
542
|
end
|
442
543
|
|
@@ -444,20 +545,20 @@ describe Rufus::Scheduler::CronLine do
|
|
444
545
|
|
445
546
|
it 'returns the shortest delta between two occurrences' do
|
446
547
|
|
447
|
-
Rufus::Scheduler::CronLine.new(
|
448
|
-
'* * * * *').frequency.
|
449
|
-
Rufus::Scheduler::CronLine.new(
|
450
|
-
'* * * * * *').frequency.
|
548
|
+
expect(Rufus::Scheduler::CronLine.new(
|
549
|
+
'* * * * *').frequency).to eq(60)
|
550
|
+
expect(Rufus::Scheduler::CronLine.new(
|
551
|
+
'* * * * * *').frequency).to eq(1)
|
451
552
|
|
452
|
-
Rufus::Scheduler::CronLine.new(
|
453
|
-
'5 23 * * *').frequency.
|
454
|
-
Rufus::Scheduler::CronLine.new(
|
455
|
-
'5 * * * *').frequency.
|
456
|
-
Rufus::Scheduler::CronLine.new(
|
457
|
-
'10,20,30 * * * *').frequency.
|
553
|
+
expect(Rufus::Scheduler::CronLine.new(
|
554
|
+
'5 23 * * *').frequency).to eq(24 * 3600)
|
555
|
+
expect(Rufus::Scheduler::CronLine.new(
|
556
|
+
'5 * * * *').frequency).to eq(3600)
|
557
|
+
expect(Rufus::Scheduler::CronLine.new(
|
558
|
+
'10,20,30 * * * *').frequency).to eq(600)
|
458
559
|
|
459
|
-
Rufus::Scheduler::CronLine.new(
|
460
|
-
'10,20,30 * * * * *').frequency.
|
560
|
+
expect(Rufus::Scheduler::CronLine.new(
|
561
|
+
'10,20,30 * * * * *').frequency).to eq(10)
|
461
562
|
end
|
462
563
|
end
|
463
564
|
|
@@ -465,17 +566,17 @@ describe Rufus::Scheduler::CronLine do
|
|
465
566
|
|
466
567
|
it 'returns the shortest delta between two occurrences' do
|
467
568
|
|
468
|
-
Rufus::Scheduler::CronLine.new(
|
469
|
-
'* * * * *').brute_frequency.
|
470
|
-
Rufus::Scheduler::CronLine.new(
|
471
|
-
'* * * * * *').brute_frequency.
|
569
|
+
expect(Rufus::Scheduler::CronLine.new(
|
570
|
+
'* * * * *').brute_frequency).to eq(60)
|
571
|
+
expect(Rufus::Scheduler::CronLine.new(
|
572
|
+
'* * * * * *').brute_frequency).to eq(1)
|
472
573
|
|
473
|
-
Rufus::Scheduler::CronLine.new(
|
474
|
-
'5 23 * * *').brute_frequency.
|
475
|
-
Rufus::Scheduler::CronLine.new(
|
476
|
-
'5 * * * *').brute_frequency.
|
477
|
-
Rufus::Scheduler::CronLine.new(
|
478
|
-
'10,20,30 * * * *').brute_frequency.
|
574
|
+
expect(Rufus::Scheduler::CronLine.new(
|
575
|
+
'5 23 * * *').brute_frequency).to eq(24 * 3600)
|
576
|
+
expect(Rufus::Scheduler::CronLine.new(
|
577
|
+
'5 * * * *').brute_frequency).to eq(3600)
|
578
|
+
expect(Rufus::Scheduler::CronLine.new(
|
579
|
+
'10,20,30 * * * *').brute_frequency).to eq(600)
|
479
580
|
|
480
581
|
#Rufus::Scheduler::CronLine.new(
|
481
582
|
# '10,20,30 * * * * *').brute_frequency.should == 10
|
@@ -513,8 +614,8 @@ describe Rufus::Scheduler::CronLine do
|
|
513
614
|
|
514
615
|
# verify the playground...
|
515
616
|
#
|
516
|
-
friday.isdst.
|
517
|
-
(friday + 24 * 3600 * 3).isdst.
|
617
|
+
expect(friday.isdst).to eq(false)
|
618
|
+
expect((friday + 24 * 3600 * 3).isdst).to eq(true)
|
518
619
|
|
519
620
|
cl0 = Rufus::Scheduler::CronLine.new('02 00 * * 1,2,3,4,5')
|
520
621
|
cl1 = Rufus::Scheduler::CronLine.new('45 08 * * 1,2,3,4,5')
|
@@ -522,14 +623,16 @@ describe Rufus::Scheduler::CronLine do
|
|
522
623
|
n0 = cl0.next_time(friday)
|
523
624
|
n1 = cl1.next_time(friday)
|
524
625
|
|
525
|
-
n0.strftime('%H:%M:%S %^a').
|
526
|
-
n1.strftime('%H:%M:%S %^a').
|
626
|
+
expect(n0.strftime('%H:%M:%S %^a')).to eq('00:02:00 MON')
|
627
|
+
expect(n1.strftime('%H:%M:%S %^a')).to eq('08:45:00 MON')
|
527
628
|
|
528
|
-
n0.isdst.
|
529
|
-
n1.isdst.
|
629
|
+
expect(n0.isdst).to eq(true)
|
630
|
+
expect(n1.isdst).to eq(true)
|
530
631
|
|
531
|
-
(
|
532
|
-
|
632
|
+
expect(
|
633
|
+
(n0 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('23:02:00 THU')
|
634
|
+
expect(
|
635
|
+
(n1 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('07:45:00 FRI')
|
533
636
|
end
|
534
637
|
end
|
535
638
|
|
@@ -552,8 +655,8 @@ describe Rufus::Scheduler::CronLine do
|
|
552
655
|
|
553
656
|
# verify the playground...
|
554
657
|
#
|
555
|
-
friday.isdst.
|
556
|
-
(friday + 24 * 3600 * 3).isdst.
|
658
|
+
expect(friday.isdst).to eq(true)
|
659
|
+
expect((friday + 24 * 3600 * 3).isdst).to eq(false)
|
557
660
|
|
558
661
|
cl0 = Rufus::Scheduler::CronLine.new('02 00 * * 1,2,3,4,5')
|
559
662
|
cl1 = Rufus::Scheduler::CronLine.new('45 08 * * 1,2,3,4,5')
|
@@ -561,14 +664,16 @@ describe Rufus::Scheduler::CronLine do
|
|
561
664
|
n0 = cl0.next_time(friday)
|
562
665
|
n1 = cl1.next_time(friday)
|
563
666
|
|
564
|
-
n0.strftime('%H:%M:%S %^a').
|
565
|
-
n1.strftime('%H:%M:%S %^a').
|
667
|
+
expect(n0.strftime('%H:%M:%S %^a')).to eq('00:02:00 MON')
|
668
|
+
expect(n1.strftime('%H:%M:%S %^a')).to eq('08:45:00 MON')
|
566
669
|
|
567
|
-
n0.isdst.
|
568
|
-
n1.isdst.
|
670
|
+
expect(n0.isdst).to eq(false)
|
671
|
+
expect(n1.isdst).to eq(false)
|
569
672
|
|
570
|
-
(
|
571
|
-
|
673
|
+
expect(
|
674
|
+
(n0 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('01:02:00 FRI')
|
675
|
+
expect(
|
676
|
+
(n1 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('09:45:00 FRI')
|
572
677
|
end
|
573
678
|
end
|
574
679
|
end
|