spec/cronline_spec.rb in rufus-scheduler-3.0.9 vs spec/cronline_spec.rb in rufus-scheduler-3.1.0
- old
+ new
@@ -3,20 +3,37 @@
# Specifying rufus-scheduler
#
# Sat Mar 21 12:55:27 JST 2009
#
-require 'tzinfo'
require 'spec_helper'
describe Rufus::Scheduler::CronLine do
def cl(cronline_string)
Rufus::Scheduler::CronLine.new(cronline_string)
end
+ def nt(cronline, now)
+ Rufus::Scheduler::CronLine.new(cronline).next_time(now)
+ end
+ def ntz(cronline, now)
+ tz = cronline.split.last
+ tu = nt(cronline, now).utc
+ in_zone(tz) { tu.getlocal }
+ end
+
+ def pt(cronline, now)
+ Rufus::Scheduler::CronLine.new(cronline).previous_time(now)
+ end
+ def ptz(cronline, now)
+ tz = cronline.split.last
+ tu = pt(cronline, now).utc
+ in_zone(tz) { tu.getlocal }
+ end
+
def match(line, time)
expect(cl(line).matches?(time)).to eq(true)
end
def no_match(line, time)
expect(cl(line).matches?(time)).to eq(false)
@@ -47,16 +64,24 @@
to_a '7 10-12 * * * *', [ [7], [10, 11, 12], nil, nil, nil, nil, nil, nil ]
to_a '1-5 * * * * *', [ [1,2,3,4,5], nil, nil, nil, nil, nil, nil, nil ]
to_a '0 0 1 1 *', [ [0], [0], [0], [1], [1], nil, nil, nil ]
- to_a '0 23-24 * * *', [ [0], [0], [23, 0], nil, nil, nil, nil, nil ]
+ if ruby18?
+ to_a '0 23-24 * * *', [ [0], [0], [0, 23], nil, nil, nil, nil, nil ]
+ else
+ to_a '0 23-24 * * *', [ [0], [0], [23, 0], nil, nil, nil, nil, nil ]
+ end
#
# as reported by Aimee Rose in
# https://github.com/jmettraux/rufus-scheduler/issues/56
- to_a '0 23-2 * * *', [ [0], [0], [23, 0, 1, 2], nil, nil, nil, nil, nil ]
+ if ruby18?
+ to_a '0 23-2 * * *', [ [0], [0], [0, 1, 2, 23], nil, nil, nil, nil, nil ]
+ else
+ to_a '0 23-2 * * *', [ [0], [0], [23, 0, 1, 2], nil, nil, nil, nil, nil ]
+ end
end
it 'rejects invalid weekday expressions' do
expect { cl '0 17 * * MON_FRI' }.to raise_error
@@ -90,12 +115,15 @@
it 'interprets cron strings with / (slashes) correctly' do
to_a(
'0 */2 * * *',
- [ [0], [0], (0..11).collect { |e| e * 2 }, nil, nil, nil, nil, nil ])
+ [ [0], [0], (0..23).select { |e| e.even? }, nil, nil, nil, nil, nil ])
to_a(
+ '0 0-23/2 * * *',
+ [ [0], [0], (0..23).select { |e| e.even? }, nil, nil, nil, nil, nil ])
+ to_a(
'0 7-23/2 * * *',
[ [0], [0], (7..23).select { |e| e.odd? }, nil, nil, nil, nil, nil ])
to_a(
'*/10 * * * *',
[ [0], [0, 10, 20, 30, 40, 50], nil, nil, nil, nil, nil, nil ])
@@ -187,60 +215,38 @@
end
end
describe '#next_time' do
- def nt(cronline, now)
- Rufus::Scheduler::CronLine.new(cronline).next_time(now)
- end
- def ntz(cronline, now)
- tz = cronline.split.last
- tu = nt(cronline, now).utc
- in_zone(tz) { tu.getlocal }
- end
-
it 'computes the next occurence correctly' do
- now = Time.at(0).getutc # Thu Jan 01 00:00:00 UTC 1970
+ in_zone 'Europe/Berlin' do
- expect(nt('* * * * *', now)).to eq(now + 60)
- expect(nt('* * * * sun', now)).to eq(now + 259200)
- expect(nt('* * * * * *', now)).to eq(now + 1)
- expect(nt('* * 13 * fri', now)).to eq(now + 3715200)
+ now = Time.at(0) - 3600
- expect(nt('10 12 13 12 *', now)).to eq(now + 29938200)
- # this one is slow (1 year == 3 seconds)
- #
- # historical note:
- # (comment made in 2006 or 2007, the underlying libs got better and
- # that slowness is gone)
+ expect(nt('* * * * *', now)).to eq(now + 60)
+ expect(nt('* * * * sun', now)).to eq(now + 259200)
+ expect(nt('* * * * * *', now)).to eq(now + 1)
+ expect(nt('* * 13 * fri', now)).to eq(now + 3715200)
- expect(nt('0 0 * * thu', now)).to eq(now + 604800)
- expect(nt('00 0 * * thu', now)).to eq(now + 604800)
+ expect(nt('10 12 13 12 *', now)).to eq(now + 29938200)
+ # this one is slow (1 year == 3 seconds)
+ #
+ # historical note:
+ # (comment made in 2006 or 2007, the underlying libs got better and
+ # that slowness is gone)
- expect(nt('0 0 * * *', now)).to eq(now + 24 * 3600)
- expect(nt('0 24 * * *', now)).to eq(now + 24 * 3600)
+ expect(nt('0 0 * * thu', now)).to eq(now + 604800)
+ expect(nt('00 0 * * thu', now)).to eq(now + 604800)
- now = local(2008, 12, 31, 23, 59, 59, 0)
+ expect(nt('0 0 * * *', now)).to eq(now + 24 * 3600)
+ expect(nt('0 24 * * *', now)).to eq(now + 24 * 3600)
- expect(nt('* * * * *', now)).to eq(now + 1)
- end
+ now = local(2008, 12, 31, 23, 59, 59, 0)
- it 'computes the next occurence correctly in UTC (TZ not specified)' do
-
- now = utc(1970, 1, 1)
-
- expect(nt('* * * * *', now)).to eq(utc(1970, 1, 1, 0, 1))
- expect(nt('* * * * sun', now)).to eq(utc(1970, 1, 4))
- expect(nt('* * * * * *', now)).to eq(utc(1970, 1, 1, 0, 0, 1))
- expect(nt('* * 13 * fri', now)).to eq(utc(1970, 2, 13))
-
- expect(nt('10 12 13 12 *', now)).to eq(utc(1970, 12, 13, 12, 10))
- # this one is slow (1 year == 3 seconds)
- expect(nt('* * 1 6 *', now)).to eq(utc(1970, 6, 1))
-
- expect(nt('0 0 * * thu', now)).to eq(utc(1970, 1, 8))
+ expect(nt('* * * * *', now)).to eq(now + 1)
+ end
end
it 'computes the next occurence correctly in local TZ (TZ not specified)' do
now = local(1970, 1, 1)
@@ -258,13 +264,11 @@
end
it 'computes the next occurence correctly in UTC (TZ specified)' do
zone = 'Europe/Stockholm'
- tz = TZInfo::Timezone.get(zone)
- now = tz.local_to_utc(local(1970, 1, 1))
- # Midnight in zone, UTC
+ now = in_zone(zone) { Time.local(1970, 1, 1) }
expect(nt("* * * * * #{zone}", now)).to eq(utc(1969, 12, 31, 23, 1))
expect(nt("* * * * sun #{zone}", now)).to eq(utc(1970, 1, 3, 23))
expect(nt("* * * * * * #{zone}", now)).to eq(utc(1969, 12, 31, 23, 0, 1))
expect(nt("* * 13 * fri #{zone}", now)).to eq(utc(1970, 2, 12, 23))
@@ -273,24 +277,10 @@
expect(nt("* * 1 6 * #{zone}", now)).to eq(utc(1970, 5, 31, 23))
expect(nt("0 0 * * thu #{zone}", now)).to eq(utc(1970, 1, 7, 23))
end
- #it 'computes the next occurence correctly in local TZ (TZ specified)' do
- # zone = 'Europe/Stockholm'
- # tz = TZInfo::Timezone.get(zone)
- # now = tz.local_to_utc(utc(1970, 1, 1)).localtime
- # # Midnight in zone, local time
- # nt("* * * * * #{zone}", now).should == local(1969, 12, 31, 18, 1)
- # nt("* * * * sun #{zone}", now).should == local(1970, 1, 3, 18)
- # nt("* * * * * * #{zone}", now).should == local(1969, 12, 31, 18, 0, 1)
- # nt("* * 13 * fri #{zone}", now).should == local(1970, 2, 12, 18)
- # nt("10 12 13 12 * #{zone}", now).should == local(1970, 12, 13, 6, 10)
- # nt("* * 1 6 * #{zone}", now).should == local(1970, 5, 31, 19)
- # nt("0 0 * * thu #{zone}", now).should == local(1970, 1, 7, 18)
- #end
-
it 'computes the next time correctly when there is a sun#2 involved' do
expect(nt('* * * * sun#1', local(1970, 1, 1))).to eq(local(1970, 1, 4))
expect(nt('* * * * sun#2', local(1970, 1, 1))).to eq(local(1970, 1, 11))
@@ -373,19 +363,10 @@
end
end
describe '#previous_time' do
- def pt(cronline, now)
- Rufus::Scheduler::CronLine.new(cronline).previous_time(now)
- end
- def ptz(cronline, now)
- tz = cronline.split.last
- tu = pt(cronline, now).utc
- in_zone(tz) { tu.getlocal }
- end
-
it 'returns the previous time the cron should have triggered' do
expect(
pt('* * * * sun', lo(1970, 1, 1))).to eq(lo(1969, 12, 28, 23, 59, 00))
expect(
@@ -436,26 +417,26 @@
end
end
describe '#matches?' do
- it 'matches correctly in UTC (TZ not specified)' do
+# it 'matches correctly in UTC (TZ not specified)' do
+#
+# match '* * * * *', utc(1970, 1, 1, 0, 1)
+# match '* * * * sun', utc(1970, 1, 4)
+# match '* * * * * *', utc(1970, 1, 1, 0, 0, 1)
+# match '* * 13 * fri', utc(1970, 2, 13)
+#
+# match '10 12 13 12 *', utc(1970, 12, 13, 12, 10)
+# match '* * 1 6 *', utc(1970, 6, 1)
+#
+# match '0 0 * * thu', utc(1970, 1, 8)
+#
+# match '0 0 1 1 *', utc(2012, 1, 1)
+# no_match '0 0 1 1 *', utc(2012, 1, 1, 1, 0)
+# end
- match '* * * * *', utc(1970, 1, 1, 0, 1)
- match '* * * * sun', utc(1970, 1, 4)
- match '* * * * * *', utc(1970, 1, 1, 0, 0, 1)
- match '* * 13 * fri', utc(1970, 2, 13)
-
- match '10 12 13 12 *', utc(1970, 12, 13, 12, 10)
- match '* * 1 6 *', utc(1970, 6, 1)
-
- match '0 0 * * thu', utc(1970, 1, 8)
-
- match '0 0 1 1 *', utc(2012, 1, 1)
- no_match '0 0 1 1 *', utc(2012, 1, 1, 1, 0)
- end
-
it 'matches correctly in local TZ (TZ not specified)' do
match '* * * * *', local(1970, 1, 1, 0, 1)
match '* * * * sun', local(1970, 1, 4)
match '* * * * * *', local(1970, 1, 1, 0, 0, 1)
@@ -544,61 +525,65 @@
describe '#frequency' do
it 'returns the shortest delta between two occurrences' do
expect(Rufus::Scheduler::CronLine.new(
- '* * * * *').frequency).to eq(60)
+ '* * * * *').frequency).to eq(60)
expect(Rufus::Scheduler::CronLine.new(
- '* * * * * *').frequency).to eq(1)
+ '* * * * * *').frequency).to eq(1)
expect(Rufus::Scheduler::CronLine.new(
- '5 23 * * *').frequency).to eq(24 * 3600)
+ '5 23 * * *').frequency).to eq(24 * 3600)
expect(Rufus::Scheduler::CronLine.new(
- '5 * * * *').frequency).to eq(3600)
+ '5 * * * *').frequency).to eq(3600)
expect(Rufus::Scheduler::CronLine.new(
- '10,20,30 * * * *').frequency).to eq(600)
+ '10,20,30 * * * *').frequency).to eq(600)
expect(Rufus::Scheduler::CronLine.new(
- '10,20,30 * * * * *').frequency).to eq(10)
+ '10,20,30 * * * * *').frequency).to eq(10)
end
end
describe '#brute_frequency' do
it 'returns the shortest delta between two occurrences' do
expect(Rufus::Scheduler::CronLine.new(
- '* * * * *').brute_frequency).to eq(60)
+ '* * * * *').brute_frequency).to eq(60)
expect(Rufus::Scheduler::CronLine.new(
- '* * * * * *').brute_frequency).to eq(1)
+ '* * * * * *').brute_frequency).to eq(1)
expect(Rufus::Scheduler::CronLine.new(
- '5 23 * * *').brute_frequency).to eq(24 * 3600)
+ '5 23 * * *').brute_frequency).to eq(24 * 3600)
expect(Rufus::Scheduler::CronLine.new(
- '5 * * * *').brute_frequency).to eq(3600)
+ '5 * * * *').brute_frequency).to eq(3600)
expect(Rufus::Scheduler::CronLine.new(
- '10,20,30 * * * *').brute_frequency).to eq(600)
+ '10,20,30 * * * *').brute_frequency).to eq(600)
#Rufus::Scheduler::CronLine.new(
# '10,20,30 * * * * *').brute_frequency.should == 10
#
# takes > 20s ...
end
+
+ # some combos only appear every other year...
+ #
+ it 'does not go into an infinite loop' do
+
+ expect(Rufus::Scheduler::CronLine.new(
+ '1 2 3 4 5').brute_frequency).to eq(31622400)
+ end
end
context 'summer time' do
# let's assume summer time jumps always occur on sundays
# cf gh-114
#
it 'schedules correctly through a switch into summer time' do
- #j = `zdump -v Europe/Berlin | grep "Sun Mar" | grep 2014`.split("\n")[0]
- #j = j.match(/^.+ (Sun Mar .+ UTC) /)[1]
- # only works on system that have a zdump...
-
in_zone 'Europe/Berlin' do
# find the summer jump
j = Time.parse('2014-02-28 12:00')
@@ -621,18 +606,18 @@
cl1 = Rufus::Scheduler::CronLine.new('45 08 * * 1,2,3,4,5')
n0 = cl0.next_time(friday)
n1 = cl1.next_time(friday)
- expect(n0.strftime('%H:%M:%S %^a')).to eq('00:02:00 MON')
+ expect(n0.strftime('%H:%M:%S %^a')).to eq('00:02:00 TUE')
expect(n1.strftime('%H:%M:%S %^a')).to eq('08:45:00 MON')
expect(n0.isdst).to eq(true)
expect(n1.isdst).to eq(true)
expect(
- (n0 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('23:02:00 THU')
+ (n0 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('23:02:00 FRI')
expect(
(n1 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('07:45:00 FRI')
end
end
@@ -672,9 +657,73 @@
expect(
(n0 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('01:02:00 FRI')
expect(
(n1 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('09:45:00 FRI')
+ end
+ end
+
+ it 'correctly increments through a DST transition' do
+
+ expect(
+ nt('* * * * * America/Los_Angeles', Time.utc(2015, 3, 8, 9, 59))
+ ).to eq(Time.utc(2015, 3, 8, 10, 00))
+ end
+
+ it 'correctly increments every minute through a DST transition' do
+
+ in_zone 'America/Los_Angeles' do
+
+ line = cl('* * * * * America/Los_Angeles')
+
+ t = Time.local(2015, 3, 8, 1, 57)
+
+ points =
+ [ 0, 1, 2, 3 ].collect do
+ t = line.next_time(t)
+ t.strftime('%H:%M:%Sl') + ' ' + t.dup.utc.strftime('%H:%M:%Su')
+ end
+
+ expect(points).to eq(
+ [
+ '01:58:00l 09:58:00u',
+ '01:59:00l 09:59:00u',
+ '03:00:00l 10:00:00u',
+ '03:01:00l 10:01:00u'
+ ]
+ )
+ end
+ end
+
+ it 'correctly decrements through a DST transition' do
+
+ expect(
+ pt('* * * * * America/Los_Angeles', Time.utc(2015, 3, 8, 10, 00))
+ ).to eq(Time.utc(2015, 3, 8, 9, 59))
+ end
+
+ it 'correctly decrements every minute through a DST transition' do
+
+ in_zone 'America/Los_Angeles' do
+
+ line = cl('* * * * * America/Los_Angeles')
+
+ t = Time.local(2015, 3, 8, 3, 2)
+
+ points =
+ [ 0, 1, 2, 3 ].collect do
+ t = line.previous_time(t)
+ t.strftime('%H:%M:%Sl') + ' ' + t.dup.utc.strftime('%H:%M:%Su')
+ end
+
+ expect(points).to eq(
+ [
+ '03:01:00l 10:01:00u',
+ '03:00:00l 10:00:00u',
+ '01:59:00l 09:59:00u',
+ '01:58:00l 09:58:00u'
+ ]
+ )
end
end
end
end