rufus-scheduler 3.1.0 → 3.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 03122e92f3b47a4af3d12b06762f5f4caa604341
4
+ data.tar.gz: 8db6b1570347d1ffa1871fe9d90163729fbf7516
5
+ SHA512:
6
+ metadata.gz: 0bf2d0ab22e975dc6832fc651dd415708a998960b4b9503865fe560c9b78284b54ac2b5957d8c912d1415776898e211eb6fe6a56c456613df85f5b4afcf35e0f
7
+ data.tar.gz: 52b001210ccea2c628e4a95e2bde023725cbb1ce9ee78bd635cfedddafcbed9851abda8eb0edb46e5816ba7ddc80e55dae256588a6caf079f9ebd126d5dbd3c7
data/CHANGELOG.txt CHANGED
@@ -2,6 +2,54 @@
2
2
  = rufus-scheduler CHANGELOG.txt
3
3
 
4
4
 
5
+ == rufus-scheduler - 3.1.9 released 2015-11-12
6
+
7
+ - fix potential RuntimeError in CronLine#prev_second,
8
+ by Alexandru https://github.com/alexandru-calinoiu
9
+
10
+
11
+ == rufus-scheduler - 3.1.8 released 2015-11-10
12
+
13
+ - stop jumping eagerly out of DST, fix for one hour jump when leaving DST
14
+ thanks Alyssa http://github.com/alyssa
15
+
16
+
17
+ == rufus-scheduler - 3.1.7 released 2015-10-15
18
+
19
+ - ack #unscheduled_at in #scheduled?, by Claude https://github.com/claudeatsafe
20
+
21
+
22
+ == rufus-scheduler - 3.1.6 released 2015-10-01
23
+
24
+ - fix job id uniqueness (JRuby), thanks 김성식 https://github.com/kssminus
25
+
26
+
27
+ == rufus-scheduler - 3.1.5 released 2015-09-25
28
+
29
+ - fix for "not a valid cronline" on "mingw" Ruby distributions, gh-166
30
+
31
+
32
+ == rufus-scheduler - 3.1.4 released 2015/08/29
33
+
34
+ - fix cron issue reported by Jesse https://github.com/jhw-at-prosperworks-com
35
+
36
+
37
+ == rufus-scheduler - 3.1.3 released 2015/06/20
38
+
39
+ - prevent Thread[:rufus_scheduler_time] -> nil, gh-156
40
+ - fix inconsistency in Job#start_work_thread
41
+
42
+
43
+ == rufus-scheduler - 3.1.2 released 2015/05/23
44
+
45
+ - avoid cron/:first_at infinite loop, thanks https://github.com/pouellet
46
+
47
+
48
+ == rufus-scheduler - 3.1.1 released 2015/04/19
49
+
50
+ - fix ZoTime.is_timezone? on OSX, thanks https://github.com/yaauie
51
+
52
+
5
53
  == rufus-scheduler - 3.1.0 released 2015/04/18
6
54
 
7
55
  - go without tzinfo (and its dependencies)
data/CREDITS.txt CHANGED
@@ -4,6 +4,13 @@
4
4
 
5
5
  == Contributors
6
6
 
7
+ - Calinoiu Alexandru Nicolae (https://github.com/alexandru-calinoiu) CronLine#prev_second fix
8
+ - Alyssa Pohahau (https://github.com/alyssa) out of DST transition specs
9
+ - Claude Vessaz (https://github.com/claudeatsafe) ack #unscheduled_at in #scheduled?
10
+ - 김성식 (https://github.com/kssminus) job id uniqueness effort
11
+ - Jesse Willet (https://github.com/jhw-at-prosperworks-com) cron vs "*/10"
12
+ - Pascal Ouellet (https://github.com/pouellet) Scheduler#timeline loop fix
13
+ - Ryan Biesemeyer (https://github.com/yaauie) ZoTime.is_timezone? on OSX
7
14
  - Ketan Padegaonkar (https://github.com/ketan) .brute_frequency improvement
8
15
  - Gabriel Gilder (https://github.com/ggilder) LA DST specs
9
16
  - Sterling Paramore (https://github.com/gnilrets) underscore TZ fix
@@ -35,6 +42,10 @@
35
42
 
36
43
  == Feedback
37
44
 
45
+ - Suisea - https://github.com/suisea - readme rewording
46
+ - Radek - http://stackoverflow.com/users/250422 - gh-166
47
+ - Patrik Ragnarsson - https://github.com/dentarg - timeout vs nil, gh-156
48
+ - twitter @adefilaedward1 - typo in readme
38
49
  - Michael Guymon - https://github.com/mguymon - #next_time vs :first_at
39
50
  - junhanamaki - https://github.com/junhanamaki - #next_time and dst ambiguities
40
51
  - kreynolds (tossrock) - inspiration for #occurrences
data/README.md CHANGED
@@ -75,10 +75,10 @@ There is no EventMachine-based scheduler anymore.
75
75
 
76
76
  ## I don't know what this Ruby thing is, where are my Rails?
77
77
 
78
- Sir, I'll drive you right to the [tracks](#so-rails).
78
+ I'll drive you right to the [tracks](#so-rails).
79
79
 
80
80
 
81
- ## Notables changes:
81
+ ## Notable changes:
82
82
 
83
83
  * As said, no more EventMachine-based scheduler
84
84
  * ```scheduler.every('100') {``` will schedule every 100 seconds (previously, it would have been 0.1s). This aligns rufus-scheduler on Ruby's ```sleep(100)```
@@ -1399,6 +1399,7 @@ s = Rufus::Scheduler.singleton
1399
1399
  s.every '1m' do
1400
1400
 
1401
1401
  Rails.logger.info "hello, it's #{Time.now}"
1402
+ Rails.logger.flush
1402
1403
  end
1403
1404
  ```
1404
1405
 
@@ -1427,6 +1428,21 @@ The rufus-scheduler singleton is instantiated in the ```config/initializers/sche
1427
1428
 
1428
1429
  *Warning*: this works well with single-process Ruby servers like Webrick and Thin. Using rufus-scheduler with Passenger or Unicorn requires a bit more knowledge and tuning, gently provided by a bit of googling and reading, see [Faq](#faq) above.
1429
1430
 
1431
+ ### rails server -d
1432
+
1433
+ (Written in reply to https://github.com/jmettraux/rufus-scheduler/issues/165 )
1434
+
1435
+ There is the handy `rails server -d` that starts a development Rails as a daemon. The annoying thing is that the scheduler as seen above is started in the main process that then gets forked and daemonized. The rufus-scheduler thread (and any other thread) gets lost, no scheduling happens.
1436
+
1437
+ I avoid running `-d` in development mode and bother about daemonizing only for production deployment.
1438
+
1439
+ These are two well crafted articles on process daemonization, please read them:
1440
+
1441
+ * http://www.mikeperham.com/2014/09/22/dont-daemonize-your-daemons/
1442
+ * http://www.mikeperham.com/2014/07/07/use-runit/
1443
+
1444
+ If, anyway, you need something like `rails server -d`, why not try `bundle exec unicorn -D` instead? In my (limited) experience, it worked out of the box (well, had to add `gem 'unicorn'` to `Gemfile` first).
1445
+
1430
1446
 
1431
1447
  ## support
1432
1448
 
@@ -186,19 +186,6 @@ class Rufus::Scheduler
186
186
  time
187
187
  end
188
188
 
189
- if RUBY_VERSION >= '1.9'
190
- def toa(item)
191
- item == nil ? nil : item.to_a
192
- end
193
- else
194
- def toi(item); item.is_a?(String) ? item.hash.abs : item.to_i; end
195
- protected :toi
196
- def toa(item)
197
- item.is_a?(Set) ? item.to_a.sort_by { |e| toi(e) } : item
198
- end
199
- end
200
- protected :toa
201
-
202
189
  # Returns an array of 6 arrays (seconds, minutes, hours, days,
203
190
  # months, weekdays).
204
191
  # This method is used by the cronline unit tests.
@@ -228,16 +215,12 @@ class Rufus::Scheduler
228
215
 
229
216
  return brute_frequency unless @seconds && @seconds.length > 1
230
217
 
231
- delta = 60
232
218
  secs = toa(@seconds)
233
- prev = secs[0]
234
219
 
235
- secs[1..-1].each do |sec|
220
+ secs[1..-1].inject([ secs[0], 60 ]) { |(prev, delta), sec|
236
221
  d = sec - prev
237
- delta = d if d < delta
238
- end
239
-
240
- delta
222
+ [ sec, d < delta ? d : delta ]
223
+ }[1]
241
224
  end
242
225
 
243
226
  # Returns the shortest delta between two potential occurences of the
@@ -288,13 +271,11 @@ class Rufus::Scheduler
288
271
  delta
289
272
  end
290
273
 
291
- protected
292
-
293
274
  def next_second(time)
294
275
 
295
- secs = @seconds.sort
276
+ secs = toa(@seconds)
296
277
 
297
- return secs.last + 60 - time.sec if time.sec > secs.last
278
+ return secs.first + 60 - time.sec if time.sec > secs.last
298
279
 
299
280
  secs.shift while secs.first < time.sec
300
281
 
@@ -303,13 +284,32 @@ class Rufus::Scheduler
303
284
 
304
285
  def prev_second(time)
305
286
 
306
- secs = @seconds.sort
287
+ secs = toa(@seconds)
288
+
289
+ return time.sec + 60 - secs.last if time.sec < secs.first
307
290
 
308
291
  secs.pop while time.sec < secs.last
309
292
 
310
293
  time.sec - secs.last
311
294
  end
312
295
 
296
+ protected
297
+
298
+ def sc_sort(a)
299
+
300
+ a.sort_by { |e| e.is_a?(String) ? 61 : e.to_i }
301
+ end
302
+
303
+ if RUBY_VERSION >= '1.9'
304
+ def toa(item)
305
+ item == nil ? nil : item.to_a
306
+ end
307
+ else
308
+ def toa(item)
309
+ item.is_a?(Set) ? sc_sort(item.to_a) : item
310
+ end
311
+ end
312
+
313
313
  WEEKDAYS = %w[ sun mon tue wed thu fri sat ]
314
314
  DAY_S = 24 * 3600
315
315
  WEEK_S = 7 * DAY_S
@@ -351,7 +351,7 @@ class Rufus::Scheduler
351
351
  end
352
352
  end
353
353
 
354
- weekdays = weekdays.uniq if weekdays
354
+ weekdays = weekdays.uniq.sort if weekdays
355
355
 
356
356
  [ weekdays, monthdays ]
357
357
  end
@@ -366,6 +366,8 @@ class Rufus::Scheduler
366
366
  "found duplicates in #{item.inspect}"
367
367
  ) if r.uniq.size < r.size
368
368
 
369
+ r = sc_sort(r)
370
+
369
371
  Set.new(r)
370
372
  end
371
373
 
@@ -284,7 +284,7 @@ module Rufus
284
284
  Thread.new do
285
285
 
286
286
  Thread.current[@scheduler.thread_key] = true
287
- Thread.current[:rufus_scheduler_job_thread] = true
287
+ Thread.current[:rufus_scheduler_work_thread] = true
288
288
 
289
289
  loop do
290
290
 
@@ -351,7 +351,7 @@ module Rufus
351
351
  self.class.name.split(':').last.downcase[0..-4],
352
352
  @scheduled_at.to_f,
353
353
  @next_time.to_f,
354
- opts.hash.abs
354
+ self.hash.abs
355
355
  ].map(&:to_s).join('_')
356
356
  end
357
357
 
@@ -473,7 +473,7 @@ module Rufus
473
473
  [
474
474
  self.class.name.split(':').last.downcase[0..-4],
475
475
  @scheduled_at.to_f,
476
- opts.hash.abs
476
+ self.hash.abs
477
477
  ].map(&:to_s).join('_')
478
478
  end
479
479
 
@@ -621,7 +621,7 @@ module Rufus
621
621
 
622
622
  def next_time_from(time)
623
623
 
624
- if @first_at == nil || @first_at < time
624
+ if @first_at == nil || @first_at <= time
625
625
  @cron_line.next_time(time)
626
626
  else
627
627
  @first_at
@@ -151,6 +151,7 @@ America/Argentina/Catamarca America/Indiana/Indianapolis
151
151
  America/North_Dakota/New_Salem America/Argentina/Rio_Gallegos
152
152
  America/Argentina/Buenos_Aires America/Argentina/ComodRivadavia
153
153
  ]
154
+ TIMEZONEs = TIMEZONES.collect(&:downcase)
154
155
 
155
156
  ##
156
157
  ## http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations
@@ -47,13 +47,19 @@ class Rufus::Scheduler
47
47
 
48
48
  t = Time.at(@seconds)
49
49
 
50
- if t.isdst
51
- t1 = Time.at(@seconds + 3600)
52
- t = t1 if t.zone != t1.zone && t.hour == t1.hour && t.min == t1.min
53
- # ambiguous TZ (getting out of DST)
54
- else
55
- t.hour # force t to compute itself
56
- end
50
+ #if t.isdst
51
+ # t1 = Time.at(@seconds + 3600)
52
+ # t = t1 if t.zone != t1.zone && t.hour == t1.hour && t.min == t1.min
53
+ # # ambiguous TZ (getting out of DST)
54
+ #else
55
+ # t.hour # force t to compute itself
56
+ #end
57
+ #
58
+ # jump out of DST as soon as possible, jumps 1h as seen from UTC
59
+
60
+ t.hour # force t to compute itself
61
+ #
62
+ # stay in DST as long as possible, no jump seen from UTC
57
63
 
58
64
  t
59
65
  end
@@ -121,17 +127,24 @@ class Rufus::Scheduler
121
127
  def self.is_timezone?(str)
122
128
 
123
129
  return false if str == nil
130
+ return false if str == '*'
131
+
132
+ return false if str.index('#')
133
+ # "sun#2", etc... On OSX would go all the way to true
124
134
 
125
135
  return true if Time.zone_offset(str)
126
- return true if str == 'Zulu'
127
136
 
128
137
  return !! (::TZInfo::Timezone.get(str) rescue nil) if defined?(::TZInfo)
129
138
 
130
- zt = ZoTime.new(0, str)
131
- t = zt.time
139
+ return true if TIMEZONES.include?(str)
140
+ return true if TIMEZONEs.include?(str)
141
+
142
+ t = ZoTime.new(0, str).time
132
143
 
133
144
  return false if t.zone == ''
134
- return false if str.match(/[a-z]/) && str.start_with?(t.zone)
145
+ return false if t.zone == 'UTC'
146
+ return false if t.utc_offset == 0 && str.start_with?(t.zone)
147
+ # 3 common fallbacks...
135
148
 
136
149
  return false if RUBY_PLATFORM.include?('java') && ! envtzable?(str)
137
150
 
@@ -39,7 +39,7 @@ module Rufus
39
39
  require 'rufus/scheduler/job_array'
40
40
  require 'rufus/scheduler/locks'
41
41
 
42
- VERSION = '3.1.0'
42
+ VERSION = '3.1.9'
43
43
 
44
44
  #
45
45
  # A common error class for rufus-scheduler
@@ -387,7 +387,7 @@ module Rufus
387
387
 
388
388
  job, job_id = fetch(job_or_job_id)
389
389
 
390
- !! (job && job.next_time != nil)
390
+ !! (job && job.unscheduled_at.nil? && job.next_time != nil)
391
391
  end
392
392
 
393
393
  # Lists all the threads associated with this scheduler.
@@ -592,11 +592,11 @@ module Rufus
592
592
 
593
593
  job = t[:rufus_scheduler_job]
594
594
  to = t[:rufus_scheduler_timeout]
595
+ ts = t[:rufus_scheduler_time]
595
596
 
596
- next unless job && to
597
+ next unless job && to && ts
597
598
  # thread might just have become inactive (job -> nil)
598
599
 
599
- ts = t[:rufus_scheduler_time]
600
600
  to = to.is_a?(Time) ? to : ts + to
601
601
 
602
602
  next if to > Time.now
@@ -7,6 +7,17 @@
7
7
 
8
8
  require 'spec_helper'
9
9
 
10
+ class Time
11
+
12
+ def to_compact_s
13
+
14
+ off = self.utc_offset / 3600
15
+ off = off >= 0 ? "+#{off}" : off.to_s
16
+
17
+ self.strftime('%H%M') + off + self.dup.utc.strftime('(%H%M)')
18
+ end
19
+ end
20
+
10
21
 
11
22
  describe Rufus::Scheduler::CronLine do
12
23
 
@@ -32,6 +43,13 @@ describe Rufus::Scheduler::CronLine do
32
43
  in_zone(tz) { tu.getlocal }
33
44
  end
34
45
 
46
+ def ns(cronline, now)
47
+ Rufus::Scheduler::CronLine.new(cronline).next_second(now)
48
+ end
49
+ def ps(cronline, now)
50
+ Rufus::Scheduler::CronLine.new(cronline).prev_second(now)
51
+ end
52
+
35
53
  def match(line, time)
36
54
  expect(cl(line).matches?(time)).to eq(true)
37
55
  end
@@ -66,30 +84,42 @@ describe Rufus::Scheduler::CronLine do
66
84
 
67
85
  to_a '0 0 1 1 *', [ [0], [0], [0], [1], [1], nil, nil, nil ]
68
86
 
69
- if ruby18?
70
- to_a '0 23-24 * * *', [ [0], [0], [0, 23], nil, nil, nil, nil, nil ]
71
- else
72
- to_a '0 23-24 * * *', [ [0], [0], [23, 0], nil, nil, nil, nil, nil ]
73
- end
87
+ to_a '52 0 * * *', [ [0], [52], [0], nil, nil, nil, nil, nil ]
88
+
89
+ #if ruby18?
90
+ # to_a '0 23-24 * * *', [ [0], [0], [0, 23], nil, nil, nil, nil, nil ]
91
+ #else
92
+ # to_a '0 23-24 * * *', [ [0], [0], [23, 0], nil, nil, nil, nil, nil ]
93
+ #end
74
94
  #
75
95
  # as reported by Aimee Rose in
76
96
  # https://github.com/jmettraux/rufus-scheduler/issues/56
77
-
78
- if ruby18?
79
- to_a '0 23-2 * * *', [ [0], [0], [0, 1, 2, 23], nil, nil, nil, nil, nil ]
80
- else
81
- to_a '0 23-2 * * *', [ [0], [0], [23, 0, 1, 2], nil, nil, nil, nil, nil ]
82
- end
97
+ to_a '0 23-24 * * *', [ [0], [0], [0, 23], nil, nil, nil, nil, nil ]
98
+
99
+ #if ruby18?
100
+ # to_a '0 23-2 * * *', [ [0], [0], [0, 1, 2, 23], nil, nil, nil, nil, nil ]
101
+ #else
102
+ # to_a '0 23-2 * * *', [ [0], [0], [23, 0, 1, 2], nil, nil, nil, nil, nil ]
103
+ #end
104
+ to_a '0 23-2 * * *', [ [0], [0], [0, 1, 2, 23], nil, nil, nil, nil, nil ]
105
+
106
+ # modulo forms work for five-field forms
107
+ to_a '*/17 * * * *', [[0], [0, 17, 34, 51], nil, nil, nil, nil, nil, nil]
108
+ to_a '13 */17 * * *', [[0], [13], [0, 17], nil, nil, nil, nil, nil]
109
+
110
+ # modulo forms work for six-field forms
111
+ to_a '*/17 * * * * *', [[0, 17, 34, 51], nil, nil, nil, nil, nil, nil, nil]
112
+ to_a '13 */17 * * * *', [[13], [0, 17, 34, 51], nil, nil, nil, nil, nil, nil]
83
113
  end
84
114
 
85
115
  it 'rejects invalid weekday expressions' do
86
116
 
87
- expect { cl '0 17 * * MON_FRI' }.to raise_error
117
+ expect { cl '0 17 * * MON_FRI' }.to raise_error(ArgumentError)
88
118
  # underline instead of dash
89
119
 
90
- expect { cl '* * * * 9' }.to raise_error
91
- expect { cl '* * * * 0-12' }.to raise_error
92
- expect { cl '* * * * BLABLA' }.to raise_error
120
+ expect { cl '* * * * 9' }.to raise_error(ArgumentError)
121
+ expect { cl '* * * * 0-12' }.to raise_error(ArgumentError)
122
+ expect { cl '* * * * BLABLA' }.to raise_error(ArgumentError)
93
123
  end
94
124
 
95
125
  it 'rejects invalid cronlines' do
@@ -109,8 +139,8 @@ describe Rufus::Scheduler::CronLine do
109
139
  '* * * * * * America/New_York',
110
140
  [ nil, nil, nil, nil, nil, nil, nil, 'America/New_York' ])
111
141
 
112
- expect { cl '* * * * * NotATimeZone' }.to raise_error
113
- expect { cl '* * * * * * NotATimeZone' }.to raise_error
142
+ expect { cl '* * * * * NotATimeZone' }.to raise_error(ArgumentError)
143
+ expect { cl '* * * * * * NotATimeZone' }.to raise_error(ArgumentError)
114
144
  end
115
145
 
116
146
  it 'interprets cron strings with / (slashes) correctly' do
@@ -213,6 +243,36 @@ describe Rufus::Scheduler::CronLine do
213
243
  # as reported by Aimee Rose in
214
244
  # https://github.com/jmettraux/rufus-scheduler/pull/58
215
245
  end
246
+
247
+ it 'sorts seconds' do
248
+
249
+ to_a(
250
+ '23,30,10 * * * * *', [ [10,23,30], nil, nil, nil, nil, nil, nil, nil ])
251
+ end
252
+
253
+ it 'sorts minutes' do
254
+
255
+ to_a(
256
+ '23,30,10 * * * * ', [ [0], [10,23,30], nil, nil, nil, nil, nil, nil ])
257
+ end
258
+
259
+ it 'sorts days' do
260
+
261
+ to_a(
262
+ '* * 14,7 * * ', [ [0], nil, nil, [7, 14], nil, nil, nil, nil ])
263
+ end
264
+
265
+ it 'sorts months' do
266
+
267
+ to_a(
268
+ '* * * 11,3,4 * ', [ [0], nil, nil, nil, [3,4,11], nil, nil, nil ])
269
+ end
270
+
271
+ it 'sorts days of week' do
272
+
273
+ to_a(
274
+ '* * * * Sun,Fri,2 ', [ [0], nil, nil, nil, nil, [0, 2, 5], nil, nil ])
275
+ end
216
276
  end
217
277
 
218
278
  describe '#next_time' do
@@ -346,7 +406,10 @@ describe Rufus::Scheduler::CronLine do
346
406
  '30 1 31 10 * America/New_York',
347
407
  ltz('America/New_York', 2004, 10, 1)
348
408
  )
349
- ).to eq(ltz('America/New_York', 2004, 10, 31, 1, 30, 0))
409
+ ).to eq(
410
+ ltz('America/New_York', 0, 30, 1, 31, 10, 2004, nil, nil, true, nil)
411
+ # EDT summer time UTC-4
412
+ )
350
413
  end
351
414
  end
352
415
 
@@ -361,6 +424,75 @@ describe Rufus::Scheduler::CronLine do
361
424
  )
362
425
  ).to eq(ltz('America/New_York', 2015, 3, 9, 2, 0, 0))
363
426
  end
427
+
428
+ it 'understands six-field crontabs' do
429
+
430
+ expect(nt('* * * * * *',local(1970,1,1,1,1,1))).to(
431
+ eq(local(1970,1,1,1,1,2))
432
+ )
433
+ expect(nt('* * * * * *',local(1970,1,1,1,1,2))).to(
434
+ eq(local(1970,1,1,1,1,3))
435
+ )
436
+ expect(nt('*/10 * * * * *',local(1970,1,1,1,1,0))).to(
437
+ eq(local(1970,1,1,1,1,10))
438
+ )
439
+ expect(nt('*/10 * * * * *',local(1970,1,1,1,1,9))).to(
440
+ eq(local(1970,1,1,1,1,10))
441
+ )
442
+ expect(nt('*/10 * * * * *',local(1970,1,1,1,1,10))).to(
443
+ eq(local(1970,1,1,1,1,20))
444
+ )
445
+ expect(nt('*/10 * * * * *',local(1970,1,1,1,1,40))).to(
446
+ eq(local(1970,1,1,1,1,50))
447
+ )
448
+ expect(nt('*/10 * * * * *',local(1970,1,1,1,1,49))).to(
449
+ eq(local(1970,1,1,1,1,50))
450
+ )
451
+ expect(nt('*/10 * * * * *',local(1970,1,1,1,1,50))).to(
452
+ eq(local(1970,1,1,1,2,00))
453
+ )
454
+ end
455
+ end
456
+
457
+ describe '#next_second' do
458
+ [
459
+ [ '*/10 * * * * *', local(1970,1,1,1,1, 0), 0 ], # 0 sec to 0s mark
460
+ [ '*/10 * * * * *', local(1970,1,1,1,1, 1), 9 ], # 9 sec to 10s mark
461
+ [ '*/10 * * * * *', local(1970,1,1,1,1, 9), 1 ], # 1 sec to 10s mark
462
+ [ '*/10 * * * * *', local(1970,1,1,1,1,10), 0 ], # 0 sec to 10s mark
463
+ [ '*/10 * * * * *', local(1970,1,1,1,1,11), 9 ], # 9 sec to 20s mark
464
+ [ '*/10 * * * * *', local(1970,1,1,1,1,19), 1 ], # 1 sec to 20s mark
465
+ [ '*/10 * * * * *', local(1970,1,1,1,1,20), 0 ], # 0 sec to 20s mark
466
+ [ '*/10 * * * * *', local(1970,1,1,1,1,21), 9 ], # 1 sec to 30s mark
467
+ # ...
468
+ [ '*/10 * * * * *', local(1970,1,1,1,1,49), 1 ], # 9 sec to 50s mark
469
+ [ '*/10 * * * * *', local(1970,1,1,1,1,50), 0 ], # 0 sec to 50s mark
470
+ [ '*/10 * * * * *', local(1970,1,1,1,1,51), 9 ],
471
+ ].each do |cronline, now, sec|
472
+ it "ensures that next_second('#{cronline}', #{now}) is #{sec}" do
473
+ expect(ns(cronline,now)).to eq(sec)
474
+ end
475
+ end
476
+ end
477
+
478
+ describe '#prev_second' do
479
+
480
+ it 'returns the time to the closest previous second' do
481
+
482
+ t = local(1970, 1, 1, 1, 1, 42)
483
+
484
+ expect(ps('35,44 * * * * *', t)).to eq(7)
485
+ end
486
+
487
+ context 'when time sec is lower then all cron seconds (gh-177)' do
488
+
489
+ it 'returns the time to the last second a minute before' do
490
+
491
+ t = local(1970, 1, 1, 1, 1, 42)
492
+
493
+ expect(ps('43,44 * * * * *', t)).to eq(58)
494
+ end
495
+ end
364
496
  end
365
497
 
366
498
  describe '#previous_time' do
@@ -380,6 +512,27 @@ describe Rufus::Scheduler::CronLine do
380
512
  pt('* * * * * sun', lo(1970, 1, 1))).to eq(lo(1969, 12, 28, 23, 59, 59))
381
513
  end
382
514
 
515
+ it 'jumps to the previous minute if necessary (gh-177)' do
516
+
517
+ t = local(1970, 12, 31, 1, 1, 0) # vanilla
518
+ expect(pt('43,44 * * * * *', t)).to eq(lo(1970, 12, 31, 1, 0, 44))
519
+
520
+ t = local(1970, 12, 31, 1, 1, 30) # 30 < 43 <---- here!
521
+ expect(pt('43,44 * * * * *', t)).to eq(lo(1970, 12, 31, 1, 0, 44))
522
+
523
+ t = local(1970, 12, 31, 1, 1, 43) # 43 <= 43 < 44
524
+ expect(pt('43,44 * * * * *', t)).to eq(lo(1970, 12, 31, 1, 0, 44))
525
+
526
+ t = local(1970, 12, 31, 1, 1, 44) # 44 <= 44
527
+ expect(pt('43,44 * * * * *', t)).to eq(lo(1970, 12, 31, 1, 1, 43))
528
+
529
+ t = local(1970, 12, 31, 1, 1, 59) # 44 < 59
530
+ expect(pt('43,44 * * * * *', t)).to eq(lo(1970, 12, 31, 1, 1, 44))
531
+
532
+ t = local(1970, 12, 31, 1, 1, 30) # a bigger jump
533
+ expect(pt('43,44 10 * * * *', t)).to eq(lo(1970, 12, 31, 0, 10, 44))
534
+ end
535
+
383
536
  # New York EST: UTC-5
384
537
  # summer (dst) EDT: UTC-4
385
538
 
@@ -400,7 +553,10 @@ describe Rufus::Scheduler::CronLine do
400
553
  '30 1 31 10 * America/New_York',
401
554
  ltz('America/New_York', 2004, 10, 31, 14, 30, 0)
402
555
  )
403
- ).to eq(ltz('America/New_York', 2004, 10, 31, 1, 30, 0))
556
+ ).to eq(
557
+ ltz('America/New_York', 0, 30, 1, 31, 10, 2004, nil, nil, false, nil)
558
+ # EST time UTC-5
559
+ )
404
560
  end
405
561
  end
406
562
 
@@ -415,6 +571,20 @@ describe Rufus::Scheduler::CronLine do
415
571
  )
416
572
  ).to eq(ltz('America/New_York', 2015, 3, 9, 2, 0, 0))
417
573
  end
574
+
575
+ it 'computes correctly when * 0,10,20' do
576
+
577
+ expect(
578
+ pt('* 0,10,20 * * *', lo(2000, 1, 1))).to eq(
579
+ lo(1999, 12, 31, 20, 59, 00))
580
+ end
581
+
582
+ it 'computes correctly when * */10' do
583
+
584
+ expect(
585
+ pt('* */10 * * *', lo(2000, 1, 1))).to eq(
586
+ lo(1999, 12, 31, 20, 59, 00))
587
+ end
418
588
  end
419
589
 
420
590
  describe '#matches?' do
@@ -541,6 +711,46 @@ describe Rufus::Scheduler::CronLine do
541
711
  expect(Rufus::Scheduler::CronLine.new(
542
712
  '10,20,30 * * * * *').frequency).to eq(10)
543
713
  end
714
+
715
+ it 'spots B-A vs C-B asymmetry in five-field forms' do
716
+
717
+ expect(Rufus::Scheduler::CronLine.new(
718
+ '10,17,30 * * * *').frequency).to eq(7 * 60)
719
+ expect(Rufus::Scheduler::CronLine.new(
720
+ '10,23,30 * * * *').frequency).to eq(7 * 60)
721
+ expect(Rufus::Scheduler::CronLine.new(
722
+ '23,10,30 * * * *').frequency).to eq(7 * 60)
723
+ end
724
+
725
+ it 'spots B-A vs C-B asymmetry in six-field forms' do
726
+
727
+ expect(Rufus::Scheduler::CronLine.new(
728
+ '10,17,30 * * * * *').frequency).to eq(7)
729
+ expect(Rufus::Scheduler::CronLine.new(
730
+ '10,23,30 * * * * *').frequency).to eq(7)
731
+ expect(Rufus::Scheduler::CronLine.new(
732
+ '23,10,30 * * * * *').frequency).to eq(7)
733
+ end
734
+
735
+ it 'handles crontab steps syntax in five-field forms' do
736
+
737
+ expect(Rufus::Scheduler::CronLine.new(
738
+ '*/10 * * * *').frequency).to eq(10 * 60)
739
+ expect(Rufus::Scheduler::CronLine.new(
740
+ '* */10 * * *').frequency).to eq(60) # "*" all minutes [0..59]
741
+ expect(Rufus::Scheduler::CronLine.new(
742
+ '0 */10 * * *').frequency).to eq(4 * 60 * 60) # 2000 to 0000
743
+ end
744
+
745
+ it 'handles crontab steps syntax in six-field forms' do
746
+
747
+ expect(Rufus::Scheduler::CronLine.new(
748
+ '*/10 * * * * *').frequency).to eq(10)
749
+ expect(Rufus::Scheduler::CronLine.new(
750
+ '* */10 * * * *').frequency).to eq(1) # "*" all seconds [0..59]
751
+ expect(Rufus::Scheduler::CronLine.new(
752
+ '0 */10 * * * *').frequency).to eq(10 * 60)
753
+ end
544
754
  end
545
755
 
546
756
  describe '#brute_frequency' do
@@ -572,6 +782,42 @@ describe Rufus::Scheduler::CronLine do
572
782
  expect(Rufus::Scheduler::CronLine.new(
573
783
  '1 2 3 4 5').brute_frequency).to eq(31622400)
574
784
  end
785
+
786
+ it 'spots B-A vs C-B asymmetry in five-field forms' do
787
+
788
+ expect(Rufus::Scheduler::CronLine.new(
789
+ '10,17,30 * * * *').brute_frequency).to eq(7 * 60)
790
+ expect(Rufus::Scheduler::CronLine.new(
791
+ '10,23,30 * * * *').brute_frequency).to eq(7 * 60)
792
+ end
793
+
794
+ it 'spots B-A vs C-B asymmetry in six-field forms' do
795
+
796
+ expect(Rufus::Scheduler::CronLine.new(
797
+ '10,17,30 * * * * *').brute_frequency).to eq(7)
798
+ expect(Rufus::Scheduler::CronLine.new(
799
+ '10,23,30 * * * * *').brute_frequency).to eq(7)
800
+ end
801
+
802
+ it 'handles crontab modulo syntax in five-field forms' do
803
+
804
+ expect(Rufus::Scheduler::CronLine.new(
805
+ '*/10 * * * *').brute_frequency).to eq(10 * 60)
806
+ expect(Rufus::Scheduler::CronLine.new(
807
+ '* */10 * * *').brute_frequency).to eq(60) # "*" all minutes [0..59]
808
+ expect(Rufus::Scheduler::CronLine.new(
809
+ '0 */10 * * *').brute_frequency).to eq(4 * 60 * 60) # 2000 to 0000
810
+ end
811
+
812
+ it 'handles crontab modulo syntax in six-field forms' do
813
+
814
+ expect(Rufus::Scheduler::CronLine.new(
815
+ '*/10 * * * * *').brute_frequency).to eq(10)
816
+ expect(Rufus::Scheduler::CronLine.new(
817
+ '* */10 * * * *').brute_frequency).to eq(1) # "*" all seconds [0..59]
818
+ expect(Rufus::Scheduler::CronLine.new(
819
+ '0 */10 * * * *').brute_frequency).to eq(10 * 60)
820
+ end
575
821
  end
576
822
 
577
823
  context 'summer time' do
@@ -678,19 +924,17 @@ describe Rufus::Scheduler::CronLine do
678
924
  t = Time.local(2015, 3, 8, 1, 57)
679
925
 
680
926
  points =
681
- [ 0, 1, 2, 3 ].collect do
927
+ 4.times.collect do
682
928
  t = line.next_time(t)
683
- t.strftime('%H:%M:%Sl') + ' ' + t.dup.utc.strftime('%H:%M:%Su')
929
+ t.to_compact_s
684
930
  end
685
931
 
686
- expect(points).to eq(
687
- [
688
- '01:58:00l 09:58:00u',
689
- '01:59:00l 09:59:00u',
690
- '03:00:00l 10:00:00u',
691
- '03:01:00l 10:01:00u'
692
- ]
693
- )
932
+ expect(points).to eq([
933
+ '0158-8(0958)',
934
+ '0159-8(0959)',
935
+ '0300-7(1000)',
936
+ '0301-7(1001)'
937
+ ])
694
938
  end
695
939
  end
696
940
 
@@ -710,19 +954,158 @@ describe Rufus::Scheduler::CronLine do
710
954
  t = Time.local(2015, 3, 8, 3, 2)
711
955
 
712
956
  points =
713
- [ 0, 1, 2, 3 ].collect do
957
+ 4.times.collect do
714
958
  t = line.previous_time(t)
715
- t.strftime('%H:%M:%Sl') + ' ' + t.dup.utc.strftime('%H:%M:%Su')
959
+ t.to_compact_s
716
960
  end
717
961
 
718
- expect(points).to eq(
719
- [
720
- '03:01:00l 10:01:00u',
721
- '03:00:00l 10:00:00u',
722
- '01:59:00l 09:59:00u',
723
- '01:58:00l 09:58:00u'
724
- ]
725
- )
962
+ expect(points).to eq([
963
+ '0301-7(1001)',
964
+ '0300-7(1000)',
965
+ '0159-8(0959)',
966
+ '0158-8(0958)'
967
+ ])
968
+ end
969
+ end
970
+
971
+ it 'correctly increments when entering DST' do
972
+
973
+ in_zone 'America/Los_Angeles' do
974
+
975
+ line = cl('*/10 * * * * America/Los_Angeles')
976
+
977
+ t = Time.local(2015, 3, 8, 1, 40)
978
+ t1 = t.dup
979
+
980
+ points = []
981
+ while t1 - t < 1 * 3600
982
+ t1 = line.next_time(t1)
983
+ points << t1.to_compact_s
984
+ end
985
+
986
+ expect(points).to eq(%w[
987
+ 0150-8(0950)
988
+ 0300-7(1000)
989
+ 0310-7(1010)
990
+ 0320-7(1020)
991
+ 0330-7(1030)
992
+ 0340-7(1040)
993
+ ])
994
+ end
995
+ end
996
+ end
997
+
998
+ context 'fall time' do
999
+
1000
+ it 'correctly increments through a DST transition' do
1001
+
1002
+ expect(
1003
+ nt('* * * * * America/Los_Angeles', Time.utc(2015, 11, 1, 9, 59))
1004
+ ).to eq(Time.utc(2015, 11, 1, 10, 00))
1005
+ end
1006
+
1007
+ it 'correctly increments every minute through a DST transition' do
1008
+
1009
+ in_zone 'America/Los_Angeles' do
1010
+
1011
+ line = cl('* * * * * America/Los_Angeles')
1012
+
1013
+ #t = Time.local(2015, 11, 1, 1, 57)
1014
+ #
1015
+ # --> 2015-11-01 01:57:00 -0800 (already PST)
1016
+
1017
+ t = Time.local(0, 57, 1, 1, 11, 2015, nil, nil, true, nil)
1018
+ #
1019
+ # --> 2015-11-01 01:57:00 -0700 (still PDT)
1020
+
1021
+ points =
1022
+ 4.times.collect do
1023
+ t = line.next_time(t)
1024
+ t.to_compact_s
1025
+ end
1026
+
1027
+ expect(points).to eq([
1028
+ '0158-7(0858)',
1029
+ '0159-7(0859)',
1030
+ '0100-8(0900)',
1031
+ '0101-8(0901)'
1032
+ ])
1033
+ end
1034
+ end
1035
+
1036
+ it 'correctly decrements through a DST transition' do
1037
+
1038
+ expect(
1039
+ pt('* * * * * America/Los_Angeles', Time.utc(2015, 11, 1, 10, 00))
1040
+ ).to eq(Time.utc(2015, 11, 1, 9, 59))
1041
+ end
1042
+
1043
+ it 'correctly decrements every minute through a DST transition' do
1044
+
1045
+ in_zone 'America/Los_Angeles' do
1046
+
1047
+ line = cl('* * * * * America/Los_Angeles')
1048
+
1049
+ t = Time.local(0, 2, 1, 1, 11, 2015, nil, nil, true, nil)
1050
+ #
1051
+ # try to force PST
1052
+
1053
+ # TODO: at some point, try to find out if the latest jRuby still
1054
+ # exhibits that behaviour, report to them if necessary
1055
+
1056
+ points =
1057
+ (0..3).collect do
1058
+ t = line.previous_time(t)
1059
+ t.to_compact_s
1060
+ end
1061
+
1062
+ if t.zone == 'PST'
1063
+ expect(points).to eq([
1064
+ '0101-8(0901)',
1065
+ '0100-8(0900)',
1066
+ '0159-7(0859)',
1067
+ '0158-7(0858)'
1068
+ ])
1069
+ else
1070
+ expect(points).to eq([
1071
+ '0101-7(0801)',
1072
+ '0100-7(0800)',
1073
+ '0059-7(0759)',
1074
+ '0058-7(0758)'
1075
+ ])
1076
+ end
1077
+ end
1078
+ end
1079
+
1080
+ it 'correctly increments when leaving DST' do
1081
+
1082
+ in_zone 'America/Los_Angeles' do
1083
+
1084
+ line = cl('*/10 * * * * America/Los_Angeles')
1085
+
1086
+ t = Time.local(2015, 11, 1, 0, 40)
1087
+ t1 = t.dup
1088
+
1089
+ points = []
1090
+ while t1 - t < 2 * 3600
1091
+ t1 = line.next_time(t1)
1092
+ points << t1.to_compact_s
1093
+ end
1094
+
1095
+ expect(points).to eq([
1096
+ '0050-7(0750)', # | PDT
1097
+ '0100-7(0800)', # |
1098
+ '0110-7(0810)', # V
1099
+ '0120-7(0820)',
1100
+ '0130-7(0830)',
1101
+ '0140-7(0840)',
1102
+ '0150-7(0850)',
1103
+ '0100-8(0900)', # + PST
1104
+ '0110-8(0910)', # |
1105
+ '0120-8(0920)', # V
1106
+ '0130-8(0930)',
1107
+ '0140-8(0940)'
1108
+ ])
726
1109
  end
727
1110
  end
728
1111
  end
data/spec/job_spec.rb CHANGED
@@ -176,6 +176,16 @@ describe Rufus::Scheduler::Job do
176
176
  expect(job.running?).to eq(true)
177
177
  expect(job.scheduled?).to eq(true)
178
178
  end
179
+
180
+ it 'returns false if job is unscheduled' do
181
+ job = @scheduler.schedule_interval('0.1s') { sleep 0.1 }
182
+ job.unschedule
183
+
184
+ sleep 0.3
185
+
186
+ expect(job.running?).to eq(false)
187
+ expect(job.scheduled?).to eq(false)
188
+ end
179
189
  end
180
190
 
181
191
  describe '#call' do
@@ -627,5 +637,35 @@ describe Rufus::Scheduler::Job do
627
637
  end
628
638
  end
629
639
  end
640
+
641
+ context 'one time job' do
642
+
643
+ describe '#determine_id' do
644
+
645
+ it 'returns unique ids' do
646
+
647
+ ids = []
648
+
649
+ 10_000.times { ids << @scheduler.in('1y') {} }
650
+
651
+ expect(ids.uniq.length).to eq(ids.length)
652
+ end
653
+ end
654
+ end
655
+
656
+ context 'repeat job' do
657
+
658
+ describe '#determine_id' do
659
+
660
+ it 'returns unique ids' do
661
+
662
+ ids = []
663
+
664
+ 10_000.times { ids << @scheduler.every('1y') {} }
665
+
666
+ expect(ids.uniq.length).to eq(ids.length)
667
+ end
668
+ end
669
+ end
630
670
  end
631
671
 
@@ -611,7 +611,7 @@ describe Rufus::Scheduler do
611
611
  end
612
612
  end
613
613
 
614
- describe '#timeline(time0, time1)' do
614
+ describe '#timeline' do
615
615
 
616
616
  it 'returns a [ [ time, job ], ... ] of job occurrences' do
617
617
 
@@ -625,6 +625,21 @@ describe Rufus::Scheduler do
625
625
  expect(a[1][0]).to be_within_1s_of(Time.now + 10 * 60)
626
626
  expect(a[1][1]).to eq(j1)
627
627
  end
628
+
629
+ it 'should not lock when running timeline with a :first_at specified' do
630
+
631
+ now = Time.now
632
+
633
+ # scheduling a cron job with a first_at and running #timeline used
634
+ # to result in an infinite loop.
635
+
636
+ @scheduler.cron('* * * * * *', :first_at => now + 3) {}
637
+
638
+ jobs = @scheduler.timeline(now, now + 4)
639
+ expect(jobs.size).to be 2
640
+ expect(jobs[0][0]).to be_within_1s_of now + 3
641
+ expect(jobs[1][0]).to be_within_1s_of now + 4
642
+ end
628
643
  end
629
644
 
630
645
  #--
data/spec/spec_helper.rb CHANGED
@@ -5,6 +5,8 @@
5
5
  # Wed Apr 17 06:00:59 JST 2013
6
6
  #
7
7
 
8
+ require 'pp'
9
+
8
10
  puts "RUBY_VERSION: #{RUBY_VERSION}"
9
11
  puts "RUBY_PLATFORM: #{RUBY_PLATFORM}"
10
12
 
data/spec/zotime_spec.rb CHANGED
@@ -73,22 +73,17 @@ describe Rufus::Scheduler::ZoTime do
73
73
  # New York EST: UTC-5
74
74
  # summer (dst) EDT: UTC-4
75
75
 
76
- it 'chooses the non DST time when there is ambiguity' do
76
+ it 'chooses the DST time when there is ambiguity' do
77
77
 
78
78
  t = ltz('America/New_York', 2004, 10, 31, 0, 30, 0)
79
79
  zt = Rufus::Scheduler::ZoTime.new(t, 'America/New_York')
80
80
  zt.add(3600)
81
81
  ztt = zt.time
82
82
 
83
- expect(ztt.to_i).to eq(1099204200)
83
+ expect(ztt.to_i).to eq(1099204200 - 3600)
84
84
 
85
- if ruby18?
86
- expect(ztt.strftime('%Y/%m/%d %H:%M:%S %Z %z')
87
- ).to eq('2004/10/31 01:30:00 EST -0500')
88
- else
89
- expect(ztt.strftime('%Y/%m/%d %H:%M:%S %Z %z')
90
- ).to eq('2004/10/31 01:30:00 EST -0500')
91
- end
85
+ expect(ztt.strftime('%Y/%m/%d %H:%M:%S %Z %z')
86
+ ).to eq('2004/10/31 01:30:00 EDT -0400')
92
87
  end
93
88
  end
94
89
 
@@ -162,17 +157,17 @@ describe Rufus::Scheduler::ZoTime do
162
157
  st3 = t3.strftime('%Y/%m/%d %H:%M:%S %Z') + " #{t3.isdst}"
163
158
 
164
159
  expect(t0.to_i).to eq(1414281599)
165
- expect(t1.to_i).to eq(1414285200)
160
+ expect(t1.to_i).to eq(1414285200 - 3600)
166
161
  expect(t2.to_i).to eq(1414285200)
167
162
  expect(t3.to_i).to eq(1414285201)
168
163
 
169
164
  expect(st0).to eq('2014/10/26 01:59:59 CEST true')
170
- expect(st1).to eq('2014/10/26 02:00:00 CET false')
165
+ expect(st1).to eq('2014/10/26 02:00:00 CEST true')
171
166
  expect(st2).to eq('2014/10/26 02:00:00 CET false')
172
167
  expect(st3).to eq('2014/10/26 02:00:01 CET false')
173
168
 
174
- expect(t1 - t0).to eq(3601)
175
- expect(t2 - t1).to eq(0)
169
+ expect(t1 - t0).to eq(1)
170
+ expect(t2 - t1).to eq(3600)
176
171
  expect(t3 - t2).to eq(1)
177
172
  end
178
173
  end
data/t.txt ADDED
@@ -0,0 +1,31 @@
1
+
2
+ JRUBY
3
+
4
+ 1) Rufus::Scheduler::CronLine fall time correctly decrements every minute through a DST transition
5
+
6
+ Failure/Error: expect(points).to eq([
7
+
8
+ expected: ["0101-8(0901)", "0100-8(0900)", "0159-7(0859)", "0158-7(0858)"]
9
+ got: ["0101-7(0801)", "0100-7(0800)", "0059-7(0759)", "0058-7(0758)"]
10
+
11
+ (compared using ==)
12
+ # ./spec/cronline_spec.rb:1013:in `(root)'
13
+ # ./spec/spec_helper.rb:69:in `in_zone'
14
+ # ./spec/cronline_spec.rb:1001:in `(root)'
15
+
16
+
17
+ RUBY1.8
18
+
19
+ 1) Rufus::Scheduler::CronLine fall time correctly decrements every minute through a DST transition
20
+
21
+ Failure/Error: expect(points).to eq([
22
+
23
+ expected: ["0101-8(0901)", "0100-8(0900)", "0159-7(0859)", "0158-7(0858)"]
24
+ got: ["0101-7(0801)", "0100-7(0800)", "0059-7(0759)", "0058-7(0758)"]
25
+
26
+ (compared using ==)
27
+ # ./spec/cronline_spec.rb:1013
28
+ # ./spec/spec_helper.rb:69:in `call'
29
+ # ./spec/spec_helper.rb:69:in `in_zone'
30
+ # ./spec/cronline_spec.rb:1001
31
+
metadata CHANGED
@@ -1,78 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rufus-scheduler
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
5
- prerelease:
4
+ version: 3.1.9
6
5
  platform: ruby
7
6
  authors:
8
7
  - John Mettraux
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2015-04-17 00:00:00.000000000 Z
11
+ date: 2015-11-11 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rake
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
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
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rspec
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: 2.13.0
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
44
39
  - !ruby/object:Gem::Version
45
40
  version: 2.13.0
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: chronic
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: tzinfo
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - ">="
68
60
  - !ruby/object:Gem::Version
69
61
  version: '0'
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - ">="
76
67
  - !ruby/object:Gem::Version
77
68
  version: '0'
78
69
  description: job scheduler for Ruby (at, cron, in and every jobs).
@@ -82,70 +73,70 @@ executables: []
82
73
  extensions: []
83
74
  extra_rdoc_files: []
84
75
  files:
76
+ - CHANGELOG.txt
77
+ - CREDITS.txt
78
+ - LICENSE.txt
79
+ - README.md
85
80
  - Rakefile
81
+ - TODO.txt
86
82
  - lib/rufus-scheduler.rb
87
83
  - lib/rufus/scheduler.rb
88
- - lib/rufus/scheduler/locks.rb
89
- - lib/rufus/scheduler/zotime.rb
90
84
  - lib/rufus/scheduler/cronline.rb
91
- - lib/rufus/scheduler/util.rb
85
+ - lib/rufus/scheduler/job_array.rb
92
86
  - lib/rufus/scheduler/jobs.rb
87
+ - lib/rufus/scheduler/locks.rb
88
+ - lib/rufus/scheduler/util.rb
93
89
  - lib/rufus/scheduler/zones.rb
94
- - lib/rufus/scheduler/job_array.rb
95
- - spec/job_spec.rb
96
- - spec/schedule_in_spec.rb
97
- - spec/zotime_spec.rb
98
- - spec/spec_helper.rb
90
+ - lib/rufus/scheduler/zotime.rb
91
+ - rufus-scheduler.gemspec
92
+ - spec/basics_spec.rb
93
+ - spec/cronline_spec.rb
94
+ - spec/error_spec.rb
99
95
  - spec/job_array_spec.rb
100
- - spec/schedule_interval_spec.rb
101
96
  - spec/job_at_spec.rb
102
- - spec/schedule_at_spec.rb
103
- - spec/error_spec.rb
104
- - spec/lock_spec.rb
105
- - spec/schedule_cron_spec.rb
97
+ - spec/job_cron_spec.rb
98
+ - spec/job_every_spec.rb
99
+ - spec/job_in_spec.rb
106
100
  - spec/job_interval_spec.rb
107
101
  - spec/job_repeat_spec.rb
108
- - spec/schedule_every_spec.rb
109
- - spec/threads_spec.rb
110
- - spec/cronline_spec.rb
102
+ - spec/job_spec.rb
103
+ - spec/lock_custom_spec.rb
104
+ - spec/lock_flock_spec.rb
111
105
  - spec/lock_lockfile_spec.rb
112
- - spec/job_in_spec.rb
106
+ - spec/lock_spec.rb
113
107
  - spec/parse_spec.rb
108
+ - spec/schedule_at_spec.rb
109
+ - spec/schedule_cron_spec.rb
110
+ - spec/schedule_every_spec.rb
111
+ - spec/schedule_in_spec.rb
112
+ - spec/schedule_interval_spec.rb
114
113
  - spec/scheduler_spec.rb
115
- - spec/lock_custom_spec.rb
116
- - spec/basics_spec.rb
117
- - spec/job_cron_spec.rb
118
- - spec/job_every_spec.rb
119
- - spec/lock_flock_spec.rb
120
- - rufus-scheduler.gemspec
121
- - CHANGELOG.txt
122
- - TODO.txt
123
- - LICENSE.txt
124
- - CREDITS.txt
125
- - README.md
114
+ - spec/spec_helper.rb
115
+ - spec/threads_spec.rb
116
+ - spec/zotime_spec.rb
117
+ - t.txt
126
118
  homepage: http://github.com/jmettraux/rufus-scheduler
127
119
  licenses:
128
120
  - MIT
121
+ metadata: {}
129
122
  post_install_message:
130
123
  rdoc_options: []
131
124
  require_paths:
132
125
  - lib
133
126
  required_ruby_version: !ruby/object:Gem::Requirement
134
- none: false
135
127
  requirements:
136
- - - ! '>='
128
+ - - ">="
137
129
  - !ruby/object:Gem::Version
138
130
  version: '0'
139
131
  required_rubygems_version: !ruby/object:Gem::Requirement
140
- none: false
141
132
  requirements:
142
- - - ! '>='
133
+ - - ">="
143
134
  - !ruby/object:Gem::Version
144
135
  version: '0'
145
136
  requirements: []
146
137
  rubyforge_project: rufus
147
- rubygems_version: 1.8.23
138
+ rubygems_version: 2.2.2
148
139
  signing_key:
149
- specification_version: 3
140
+ specification_version: 4
150
141
  summary: job scheduler for Ruby (at, cron, in and every jobs)
151
142
  test_files: []