rufus-scheduler 3.0.0 → 3.0.9
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.
- data/CHANGELOG.txt +63 -0
- data/CREDITS.txt +16 -0
- data/LICENSE.txt +1 -1
- data/README.md +389 -7
- data/Rakefile +0 -1
- data/TODO.txt +4 -0
- data/lib/rufus/scheduler/cronline.rb +109 -28
- data/lib/rufus/scheduler/job_array.rb +8 -1
- data/lib/rufus/scheduler/jobs.rb +127 -43
- data/lib/rufus/scheduler/locks.rb +95 -0
- data/lib/rufus/scheduler/util.rb +39 -28
- data/lib/rufus/scheduler.rb +150 -46
- data/rufus-scheduler.gemspec +2 -1
- data/spec/basics_spec.rb +54 -0
- data/spec/cronline_spec.rb +349 -92
- data/spec/error_spec.rb +30 -7
- data/spec/job_array_spec.rb +2 -2
- data/spec/job_at_spec.rb +4 -4
- data/spec/job_cron_spec.rb +42 -3
- data/spec/job_every_spec.rb +24 -5
- data/spec/job_interval_spec.rb +5 -5
- data/spec/job_repeat_spec.rb +86 -38
- data/spec/job_spec.rb +172 -55
- data/spec/lock_custom_spec.rb +47 -0
- data/spec/lock_flock_spec.rb +47 -0
- data/spec/{lockfile_spec.rb → lock_lockfile_spec.rb} +5 -5
- data/spec/lock_spec.rb +59 -0
- data/spec/parse_spec.rb +138 -76
- 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 +213 -119
- data/spec/spec_helper.rb +62 -1
- data/spec/threads_spec.rb +24 -3
- metadata +58 -37
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,26 +59,33 @@ 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
|
|
76
76
|
|
|
77
|
-
to_a
|
|
78
|
-
to_a
|
|
77
|
+
to_a('* * * * * EST', [ [0], nil, nil, nil, nil, nil, nil, 'EST' ])
|
|
78
|
+
to_a('* * * * * * EST', [ nil, nil, nil, nil, nil, nil, nil, 'EST' ])
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
to_a(
|
|
81
|
+
'* * * * * * America/Chicago',
|
|
82
|
+
[ nil, nil, nil, nil, nil, nil, nil, 'America/Chicago' ])
|
|
83
|
+
to_a(
|
|
84
|
+
'* * * * * * America/New_York',
|
|
85
|
+
[ nil, nil, nil, nil, nil, nil, nil, 'America/New_York' ])
|
|
86
|
+
|
|
87
|
+
expect { cl '* * * * * NotATimeZone' }.to raise_error
|
|
88
|
+
expect { cl '* * * * * * NotATimeZone' }.to raise_error
|
|
82
89
|
end
|
|
83
90
|
|
|
84
91
|
it 'interprets cron strings with / (slashes) correctly' do
|
|
@@ -109,54 +116,71 @@ describe Rufus::Scheduler::CronLine do
|
|
|
109
116
|
[ [0], [ 0, 10, 20, 30, 40, 50], nil, nil, nil, nil, nil, nil ])
|
|
110
117
|
end
|
|
111
118
|
|
|
119
|
+
it 'rejects / for days (every other wednesday)' do
|
|
120
|
+
|
|
121
|
+
expect {
|
|
122
|
+
Rufus::Scheduler::CronLine.new('* * * * wed/2')
|
|
123
|
+
}.to raise_error(ArgumentError)
|
|
124
|
+
end
|
|
125
|
+
|
|
112
126
|
it 'does not support ranges for monthdays (sun#1-sun#2)' do
|
|
113
127
|
|
|
114
|
-
|
|
128
|
+
expect {
|
|
115
129
|
Rufus::Scheduler::CronLine.new('* * * * sun#1-sun#2')
|
|
116
|
-
}.
|
|
130
|
+
}.to raise_error(ArgumentError)
|
|
117
131
|
end
|
|
118
132
|
|
|
119
133
|
it 'accepts items with initial 0' do
|
|
120
134
|
|
|
121
|
-
to_a
|
|
122
|
-
|
|
123
|
-
to_a
|
|
124
|
-
|
|
125
|
-
to_a
|
|
126
|
-
|
|
127
|
-
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 ])
|
|
128
149
|
end
|
|
129
150
|
|
|
130
151
|
it 'interprets cron strings with L correctly' do
|
|
131
152
|
|
|
132
|
-
to_a
|
|
133
|
-
|
|
134
|
-
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 ])
|
|
135
159
|
end
|
|
136
160
|
|
|
137
161
|
it 'does not support ranges for L' do
|
|
138
162
|
|
|
139
|
-
|
|
140
|
-
|
|
163
|
+
expect { cl '* * 15-L * *'}.to raise_error(ArgumentError)
|
|
164
|
+
expect { cl '* * L/4 * *'}.to raise_error(ArgumentError)
|
|
141
165
|
end
|
|
142
166
|
|
|
143
167
|
it 'does not support multiple Ls' do
|
|
144
168
|
|
|
145
|
-
|
|
169
|
+
expect { cl '* * L,L * *'}.to raise_error(ArgumentError)
|
|
146
170
|
end
|
|
147
171
|
|
|
148
172
|
it 'raises if L is used for something else than days' do
|
|
149
173
|
|
|
150
|
-
|
|
174
|
+
expect { cl '* L * * *'}.to raise_error(ArgumentError)
|
|
151
175
|
end
|
|
152
176
|
|
|
153
177
|
it 'raises for out of range input' do
|
|
154
178
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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)
|
|
160
184
|
#
|
|
161
185
|
# as reported by Aimee Rose in
|
|
162
186
|
# https://github.com/jmettraux/rufus-scheduler/pull/58
|
|
@@ -168,64 +192,69 @@ describe Rufus::Scheduler::CronLine do
|
|
|
168
192
|
def nt(cronline, now)
|
|
169
193
|
Rufus::Scheduler::CronLine.new(cronline).next_time(now)
|
|
170
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
|
|
171
200
|
|
|
172
201
|
it 'computes the next occurence correctly' do
|
|
173
202
|
|
|
174
203
|
now = Time.at(0).getutc # Thu Jan 01 00:00:00 UTC 1970
|
|
175
204
|
|
|
176
|
-
nt('* * * * *', now).
|
|
177
|
-
nt('* * * * sun', now).
|
|
178
|
-
nt('* * * * * *', now).
|
|
179
|
-
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)
|
|
180
209
|
|
|
181
|
-
nt('10 12 13 12 *', now).
|
|
210
|
+
expect(nt('10 12 13 12 *', now)).to eq(now + 29938200)
|
|
182
211
|
# this one is slow (1 year == 3 seconds)
|
|
183
212
|
#
|
|
184
213
|
# historical note:
|
|
185
214
|
# (comment made in 2006 or 2007, the underlying libs got better and
|
|
186
215
|
# that slowness is gone)
|
|
187
216
|
|
|
188
|
-
nt('0 0 * * thu', now).
|
|
189
|
-
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)
|
|
190
219
|
|
|
191
|
-
nt('0 0 * * *', now).
|
|
192
|
-
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)
|
|
193
222
|
|
|
194
223
|
now = local(2008, 12, 31, 23, 59, 59, 0)
|
|
195
224
|
|
|
196
|
-
nt('* * * * *', now).
|
|
225
|
+
expect(nt('* * * * *', now)).to eq(now + 1)
|
|
197
226
|
end
|
|
198
227
|
|
|
199
228
|
it 'computes the next occurence correctly in UTC (TZ not specified)' do
|
|
200
229
|
|
|
201
230
|
now = utc(1970, 1, 1)
|
|
202
231
|
|
|
203
|
-
nt('* * * * *', now).
|
|
204
|
-
nt('* * * * sun', now).
|
|
205
|
-
nt('* * * * * *', now).
|
|
206
|
-
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))
|
|
207
236
|
|
|
208
|
-
nt('10 12 13 12 *', now).
|
|
237
|
+
expect(nt('10 12 13 12 *', now)).to eq(utc(1970, 12, 13, 12, 10))
|
|
209
238
|
# this one is slow (1 year == 3 seconds)
|
|
210
|
-
nt('* * 1 6 *', now).
|
|
239
|
+
expect(nt('* * 1 6 *', now)).to eq(utc(1970, 6, 1))
|
|
211
240
|
|
|
212
|
-
nt('0 0 * * thu', now).
|
|
241
|
+
expect(nt('0 0 * * thu', now)).to eq(utc(1970, 1, 8))
|
|
213
242
|
end
|
|
214
243
|
|
|
215
244
|
it 'computes the next occurence correctly in local TZ (TZ not specified)' do
|
|
216
245
|
|
|
217
246
|
now = local(1970, 1, 1)
|
|
218
247
|
|
|
219
|
-
nt('* * * * *', now).
|
|
220
|
-
nt('* * * * sun', now).
|
|
221
|
-
nt('* * * * * *', now).
|
|
222
|
-
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))
|
|
223
252
|
|
|
224
|
-
nt('10 12 13 12 *', now).
|
|
253
|
+
expect(nt('10 12 13 12 *', now)).to eq(local(1970, 12, 13, 12, 10))
|
|
225
254
|
# this one is slow (1 year == 3 seconds)
|
|
226
|
-
nt('* * 1 6 *', now).
|
|
255
|
+
expect(nt('* * 1 6 *', now)).to eq(local(1970, 6, 1))
|
|
227
256
|
|
|
228
|
-
nt('0 0 * * thu', now).
|
|
257
|
+
expect(nt('0 0 * * thu', now)).to eq(local(1970, 1, 8))
|
|
229
258
|
end
|
|
230
259
|
|
|
231
260
|
it 'computes the next occurence correctly in UTC (TZ specified)' do
|
|
@@ -235,15 +264,15 @@ describe Rufus::Scheduler::CronLine do
|
|
|
235
264
|
now = tz.local_to_utc(local(1970, 1, 1))
|
|
236
265
|
# Midnight in zone, UTC
|
|
237
266
|
|
|
238
|
-
nt("* * * * * #{zone}", now).
|
|
239
|
-
nt("* * * * sun #{zone}", now).
|
|
240
|
-
nt("* * * * * * #{zone}", now).
|
|
241
|
-
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))
|
|
242
271
|
|
|
243
|
-
nt("10 12 13 12 * #{zone}", now).
|
|
244
|
-
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))
|
|
245
274
|
|
|
246
|
-
nt("0 0 * * thu #{zone}", now).
|
|
275
|
+
expect(nt("0 0 * * thu #{zone}", now)).to eq(utc(1970, 1, 7, 23))
|
|
247
276
|
end
|
|
248
277
|
|
|
249
278
|
#it 'computes the next occurence correctly in local TZ (TZ specified)' do
|
|
@@ -262,45 +291,85 @@ describe Rufus::Scheduler::CronLine do
|
|
|
262
291
|
|
|
263
292
|
it 'computes the next time correctly when there is a sun#2 involved' do
|
|
264
293
|
|
|
265
|
-
nt('* * * * sun#1', local(1970, 1, 1)).
|
|
266
|
-
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))
|
|
267
296
|
|
|
268
|
-
nt('* * * * sun#2', local(1970, 1, 12)).
|
|
297
|
+
expect(nt('* * * * sun#2', local(1970, 1, 12))).to eq(local(1970, 2, 8))
|
|
269
298
|
end
|
|
270
299
|
|
|
271
|
-
it 'computes
|
|
300
|
+
it 'computes next time correctly when there is a sun#2,sun#3 involved' do
|
|
272
301
|
|
|
273
|
-
|
|
274
|
-
|
|
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))
|
|
275
306
|
end
|
|
276
307
|
|
|
277
308
|
it 'understands sun#L' do
|
|
278
309
|
|
|
279
|
-
nt('* * * * sun#L', local(1970, 1, 1)).
|
|
310
|
+
expect(nt('* * * * sun#L', local(1970, 1, 1))).to eq(local(1970, 1, 25))
|
|
280
311
|
end
|
|
281
312
|
|
|
282
313
|
it 'understands sun#-1' do
|
|
283
314
|
|
|
284
|
-
nt('* * * * sun#-1', local(1970, 1, 1)).
|
|
315
|
+
expect(nt('* * * * sun#-1', local(1970, 1, 1))).to eq(local(1970, 1, 25))
|
|
285
316
|
end
|
|
286
317
|
|
|
287
318
|
it 'understands sun#-2' do
|
|
288
319
|
|
|
289
|
-
nt('* * * * sun#-2', local(1970, 1, 1)).
|
|
320
|
+
expect(nt('* * * * sun#-2', local(1970, 1, 1))).to eq(local(1970, 1, 18))
|
|
290
321
|
end
|
|
291
322
|
|
|
292
323
|
it 'computes the next time correctly when "L" (last day of month)' do
|
|
293
324
|
|
|
294
|
-
nt('* * L * *', lo(1970, 1, 1)).
|
|
295
|
-
nt('* * L * *', lo(1970, 2, 1)).
|
|
296
|
-
nt('* * L * *', lo(1972, 2, 1)).
|
|
297
|
-
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))
|
|
298
329
|
end
|
|
299
330
|
|
|
300
331
|
it 'returns a time with subseconds chopped off' do
|
|
301
332
|
|
|
302
|
-
|
|
303
|
-
|
|
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))
|
|
304
373
|
end
|
|
305
374
|
end
|
|
306
375
|
|
|
@@ -309,14 +378,61 @@ describe Rufus::Scheduler::CronLine do
|
|
|
309
378
|
def pt(cronline, now)
|
|
310
379
|
Rufus::Scheduler::CronLine.new(cronline).previous_time(now)
|
|
311
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
|
|
312
386
|
|
|
313
387
|
it 'returns the previous time the cron should have triggered' do
|
|
314
388
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
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
|
|
318
429
|
|
|
319
|
-
|
|
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))
|
|
320
436
|
end
|
|
321
437
|
end
|
|
322
438
|
|
|
@@ -388,6 +504,23 @@ describe Rufus::Scheduler::CronLine do
|
|
|
388
504
|
match '* * * * sun#2,sun#3', local(1970, 1, 18)
|
|
389
505
|
no_match '* * * * sun#2,sun#3', local(1970, 1, 25)
|
|
390
506
|
end
|
|
507
|
+
|
|
508
|
+
it 'matches correctly for seconds' do
|
|
509
|
+
|
|
510
|
+
match '* * * * * *', local(1970, 1, 11)
|
|
511
|
+
match '* * * * * *', local(1970, 1, 11, 0, 0, 13)
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
it 'matches correctly for seconds / interval' do
|
|
515
|
+
|
|
516
|
+
match '*/2 * * * * *', local(1970, 1, 11)
|
|
517
|
+
match '*/5 * * * * *', local(1970, 1, 11)
|
|
518
|
+
match '*/5 * * * * *', local(1970, 1, 11, 0, 0, 0)
|
|
519
|
+
no_match '*/5 * * * * *', local(1970, 1, 11, 0, 0, 1)
|
|
520
|
+
match '*/5 * * * * *', local(1970, 1, 11, 0, 0, 5)
|
|
521
|
+
match '*/2 * * * * *', local(1970, 1, 11, 0, 0, 2)
|
|
522
|
+
match '*/2 * * * * *', local(1970, 1, 11, 0, 0, 2, 500)
|
|
523
|
+
end
|
|
391
524
|
end
|
|
392
525
|
|
|
393
526
|
describe '#monthdays' do
|
|
@@ -400,11 +533,11 @@ describe Rufus::Scheduler::CronLine do
|
|
|
400
533
|
|
|
401
534
|
cl = Rufus::Scheduler::CronLine.new('* * * * *')
|
|
402
535
|
|
|
403
|
-
cl.monthdays(local(1970, 1, 1)).
|
|
404
|
-
cl.monthdays(local(1970, 1, 7)).
|
|
405
|
-
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 ])
|
|
406
539
|
|
|
407
|
-
cl.monthdays(local(2011, 3, 11)).
|
|
540
|
+
expect(cl.monthdays(local(2011, 3, 11))).to eq(%w[ fri#2 fri#-3 ])
|
|
408
541
|
end
|
|
409
542
|
end
|
|
410
543
|
|
|
@@ -412,12 +545,136 @@ describe Rufus::Scheduler::CronLine do
|
|
|
412
545
|
|
|
413
546
|
it 'returns the shortest delta between two occurrences' do
|
|
414
547
|
|
|
415
|
-
Rufus::Scheduler::CronLine.new(
|
|
416
|
-
|
|
548
|
+
expect(Rufus::Scheduler::CronLine.new(
|
|
549
|
+
'* * * * *').frequency).to eq(60)
|
|
550
|
+
expect(Rufus::Scheduler::CronLine.new(
|
|
551
|
+
'* * * * * *').frequency).to eq(1)
|
|
552
|
+
|
|
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)
|
|
559
|
+
|
|
560
|
+
expect(Rufus::Scheduler::CronLine.new(
|
|
561
|
+
'10,20,30 * * * * *').frequency).to eq(10)
|
|
562
|
+
end
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
describe '#brute_frequency' do
|
|
566
|
+
|
|
567
|
+
it 'returns the shortest delta between two occurrences' do
|
|
417
568
|
|
|
418
|
-
Rufus::Scheduler::CronLine.new(
|
|
419
|
-
|
|
420
|
-
Rufus::Scheduler::CronLine.new(
|
|
569
|
+
expect(Rufus::Scheduler::CronLine.new(
|
|
570
|
+
'* * * * *').brute_frequency).to eq(60)
|
|
571
|
+
expect(Rufus::Scheduler::CronLine.new(
|
|
572
|
+
'* * * * * *').brute_frequency).to eq(1)
|
|
573
|
+
|
|
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)
|
|
580
|
+
|
|
581
|
+
#Rufus::Scheduler::CronLine.new(
|
|
582
|
+
# '10,20,30 * * * * *').brute_frequency.should == 10
|
|
583
|
+
#
|
|
584
|
+
# takes > 20s ...
|
|
585
|
+
end
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
context 'summer time' do
|
|
589
|
+
|
|
590
|
+
# let's assume summer time jumps always occur on sundays
|
|
591
|
+
|
|
592
|
+
# cf gh-114
|
|
593
|
+
#
|
|
594
|
+
it 'schedules correctly through a switch into summer time' do
|
|
595
|
+
|
|
596
|
+
#j = `zdump -v Europe/Berlin | grep "Sun Mar" | grep 2014`.split("\n")[0]
|
|
597
|
+
#j = j.match(/^.+ (Sun Mar .+ UTC) /)[1]
|
|
598
|
+
# only works on system that have a zdump...
|
|
599
|
+
|
|
600
|
+
in_zone 'Europe/Berlin' do
|
|
601
|
+
|
|
602
|
+
# find the summer jump
|
|
603
|
+
|
|
604
|
+
j = Time.parse('2014-02-28 12:00')
|
|
605
|
+
loop do
|
|
606
|
+
jj = j + 24 * 3600
|
|
607
|
+
break if jj.isdst
|
|
608
|
+
j = jj
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
# test
|
|
612
|
+
|
|
613
|
+
friday = j - 24 * 3600 # one day before
|
|
614
|
+
|
|
615
|
+
# verify the playground...
|
|
616
|
+
#
|
|
617
|
+
expect(friday.isdst).to eq(false)
|
|
618
|
+
expect((friday + 24 * 3600 * 3).isdst).to eq(true)
|
|
619
|
+
|
|
620
|
+
cl0 = Rufus::Scheduler::CronLine.new('02 00 * * 1,2,3,4,5')
|
|
621
|
+
cl1 = Rufus::Scheduler::CronLine.new('45 08 * * 1,2,3,4,5')
|
|
622
|
+
|
|
623
|
+
n0 = cl0.next_time(friday)
|
|
624
|
+
n1 = cl1.next_time(friday)
|
|
625
|
+
|
|
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')
|
|
628
|
+
|
|
629
|
+
expect(n0.isdst).to eq(true)
|
|
630
|
+
expect(n1.isdst).to eq(true)
|
|
631
|
+
|
|
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')
|
|
636
|
+
end
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
it 'schedules correctly through a switch out of summer time' do
|
|
640
|
+
|
|
641
|
+
in_zone 'Europe/Berlin' do
|
|
642
|
+
|
|
643
|
+
# find the winter jump
|
|
644
|
+
|
|
645
|
+
j = Time.parse('2014-08-31 12:00')
|
|
646
|
+
loop do
|
|
647
|
+
jj = j + 24 * 3600
|
|
648
|
+
break if jj.isdst == false
|
|
649
|
+
j = jj
|
|
650
|
+
end
|
|
651
|
+
|
|
652
|
+
# test
|
|
653
|
+
|
|
654
|
+
friday = j - 24 * 3600 # one day before
|
|
655
|
+
|
|
656
|
+
# verify the playground...
|
|
657
|
+
#
|
|
658
|
+
expect(friday.isdst).to eq(true)
|
|
659
|
+
expect((friday + 24 * 3600 * 3).isdst).to eq(false)
|
|
660
|
+
|
|
661
|
+
cl0 = Rufus::Scheduler::CronLine.new('02 00 * * 1,2,3,4,5')
|
|
662
|
+
cl1 = Rufus::Scheduler::CronLine.new('45 08 * * 1,2,3,4,5')
|
|
663
|
+
|
|
664
|
+
n0 = cl0.next_time(friday)
|
|
665
|
+
n1 = cl1.next_time(friday)
|
|
666
|
+
|
|
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')
|
|
669
|
+
|
|
670
|
+
expect(n0.isdst).to eq(false)
|
|
671
|
+
expect(n1.isdst).to eq(false)
|
|
672
|
+
|
|
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')
|
|
677
|
+
end
|
|
421
678
|
end
|
|
422
679
|
end
|
|
423
680
|
end
|