spec/cronline_spec.rb in rufus-scheduler-3.1.3 vs spec/cronline_spec.rb in rufus-scheduler-3.1.4

- old
+ new

@@ -30,10 +30,14 @@ tz = cronline.split.last tu = pt(cronline, now).utc in_zone(tz) { tu.getlocal } end + def ns(cronline, now) + Rufus::Scheduler::CronLine.new(cronline).next_second(now) + 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) @@ -66,24 +70,34 @@ to_a '0 0 1 1 *', [ [0], [0], [0], [1], [1], nil, nil, nil ] to_a '52 0 * * *', [ [0], [52], [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 + #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-24 * * *', [ [0], [0], [0, 23], 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 + #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 + to_a '0 23-2 * * *', [ [0], [0], [0, 1, 2, 23], nil, nil, nil, nil, nil ] + + # modulo forms work for five-field forms + to_a '*/17 * * * *', [[0], [0, 17, 34, 51], nil, nil, nil, nil, nil, nil] + to_a '13 */17 * * *', [[0], [13], [0, 17], nil, nil, nil, nil, nil] + + # modulo forms work for six-field forms + to_a '*/17 * * * * *', [[0, 17, 34, 51], nil, nil, nil, nil, nil, nil, nil] + to_a '13 */17 * * * *', [[13], [0, 17, 34, 51], nil, nil, nil, nil, nil, nil] end it 'rejects invalid weekday expressions' do expect { cl '0 17 * * MON_FRI' }.to raise_error @@ -213,10 +227,40 @@ expect { cl '* 25 * * *'}.to raise_error(ArgumentError) # # as reported by Aimee Rose in # https://github.com/jmettraux/rufus-scheduler/pull/58 end + + it 'sorts seconds' do + + to_a( + '23,30,10 * * * * *', [ [10,23,30], nil, nil, nil, nil, nil, nil, nil ]) + end + + it 'sorts minutes' do + + to_a( + '23,30,10 * * * * ', [ [0], [10,23,30], nil, nil, nil, nil, nil, nil ]) + end + + it 'sorts days' do + + to_a( + '* * 14,7 * * ', [ [0], nil, nil, [7, 14], nil, nil, nil, nil ]) + end + + it 'sorts months' do + + to_a( + '* * * 11,3,4 * ', [ [0], nil, nil, nil, [3,4,11], nil, nil, nil ]) + end + + it 'sorts days of week' do + + to_a( + '* * * * Sun,Fri,2 ', [ [0], nil, nil, nil, nil, [0, 2, 5], nil, nil ]) + end end describe '#next_time' do it 'computes the next occurence correctly' do @@ -361,12 +405,61 @@ '0 2 9 3 * America/New_York', ltz('America/New_York', 2014, 3, 1) ) ).to eq(ltz('America/New_York', 2015, 3, 9, 2, 0, 0)) end + + it 'understands six-field crontabs' do + + expect(nt('* * * * * *',local(1970,1,1,1,1,1))).to( + eq(local(1970,1,1,1,1,2)) + ) + expect(nt('* * * * * *',local(1970,1,1,1,1,2))).to( + eq(local(1970,1,1,1,1,3)) + ) + expect(nt('*/10 * * * * *',local(1970,1,1,1,1,0))).to( + eq(local(1970,1,1,1,1,10)) + ) + expect(nt('*/10 * * * * *',local(1970,1,1,1,1,9))).to( + eq(local(1970,1,1,1,1,10)) + ) + expect(nt('*/10 * * * * *',local(1970,1,1,1,1,10))).to( + eq(local(1970,1,1,1,1,20)) + ) + expect(nt('*/10 * * * * *',local(1970,1,1,1,1,40))).to( + eq(local(1970,1,1,1,1,50)) + ) + expect(nt('*/10 * * * * *',local(1970,1,1,1,1,49))).to( + eq(local(1970,1,1,1,1,50)) + ) + expect(nt('*/10 * * * * *',local(1970,1,1,1,1,50))).to( + eq(local(1970,1,1,1,2,00)) # FAILS: skips a minute to 2:50, not 2:00 + ) + end end + describe '#next_second' do + [ + [ '*/10 * * * * *', local(1970,1,1,1,1, 0), 0 ], # 0 sec to 0s mark + [ '*/10 * * * * *', local(1970,1,1,1,1, 1), 9 ], # 9 sec to 10s mark + [ '*/10 * * * * *', local(1970,1,1,1,1, 9), 1 ], # 1 sec to 10s mark + [ '*/10 * * * * *', local(1970,1,1,1,1,10), 0 ], # 0 sec to 10s mark + [ '*/10 * * * * *', local(1970,1,1,1,1,11), 9 ], # 9 sec to 20s mark + [ '*/10 * * * * *', local(1970,1,1,1,1,19), 1 ], # 1 sec to 20s mark + [ '*/10 * * * * *', local(1970,1,1,1,1,20), 0 ], # 0 sec to 20s mark + [ '*/10 * * * * *', local(1970,1,1,1,1,21), 9 ], # 1 sec to 30s mark + # ... + [ '*/10 * * * * *', local(1970,1,1,1,1,49), 1 ], # 9 sec to 50s mark + [ '*/10 * * * * *', local(1970,1,1,1,1,50), 0 ], # 0 sec to 50s mark + [ '*/10 * * * * *', local(1970,1,1,1,1,51), 9 ], # FAILS: gives 59 + ].each do |cronline,now,sec| + it "understands that next_second('#{cronline}',#{now}) is #{sec}" do + expect(ns(cronline,now)).to eq(sec) + end + end + end + describe '#previous_time' do it 'returns the previous time the cron should have triggered' do expect( @@ -415,10 +508,24 @@ '0 2 9 3 * America/New_York', ltz('America/New_York', 2015, 3, 9, 12, 0, 0) ) ).to eq(ltz('America/New_York', 2015, 3, 9, 2, 0, 0)) end + + it 'computes correctly when * 0,10,20' do + + expect( + pt('* 0,10,20 * * *', lo(2000, 1, 1))).to eq( + lo(1999, 12, 31, 20, 59, 00)) + end + + it 'computes correctly when * */10' do + + expect( + pt('* */10 * * *', lo(2000, 1, 1))).to eq( + lo(1999, 12, 31, 20, 59, 00)) + end end describe '#matches?' do # it 'matches correctly in UTC (TZ not specified)' do @@ -541,10 +648,50 @@ '10,20,30 * * * *').frequency).to eq(600) expect(Rufus::Scheduler::CronLine.new( '10,20,30 * * * * *').frequency).to eq(10) end + + it 'spots B-A vs C-B asymmetry in five-field forms' do + + expect(Rufus::Scheduler::CronLine.new( + '10,17,30 * * * *').frequency).to eq(7 * 60) + expect(Rufus::Scheduler::CronLine.new( + '10,23,30 * * * *').frequency).to eq(7 * 60) + expect(Rufus::Scheduler::CronLine.new( + '23,10,30 * * * *').frequency).to eq(7 * 60) + end + + it 'spots B-A vs C-B asymmetry in six-field forms' do + + expect(Rufus::Scheduler::CronLine.new( + '10,17,30 * * * * *').frequency).to eq(7) + expect(Rufus::Scheduler::CronLine.new( + '10,23,30 * * * * *').frequency).to eq(7) + expect(Rufus::Scheduler::CronLine.new( + '23,10,30 * * * * *').frequency).to eq(7) + end + + it 'handles crontab steps syntax in five-field forms' do + + expect(Rufus::Scheduler::CronLine.new( + '*/10 * * * *').frequency).to eq(10 * 60) + expect(Rufus::Scheduler::CronLine.new( + '* */10 * * *').frequency).to eq(60) # "*" all minutes [0..59] + expect(Rufus::Scheduler::CronLine.new( + '0 */10 * * *').frequency).to eq(4 * 60 * 60) # 2000 to 0000 + end + + it 'handles crontab steps syntax in six-field forms' do + + expect(Rufus::Scheduler::CronLine.new( + '*/10 * * * * *').frequency).to eq(10) + expect(Rufus::Scheduler::CronLine.new( + '* */10 * * * *').frequency).to eq(1) # "*" all seconds [0..59] + expect(Rufus::Scheduler::CronLine.new( + '0 */10 * * * *').frequency).to eq(10 * 60) + end end describe '#brute_frequency' do it 'returns the shortest delta between two occurrences' do @@ -571,9 +718,45 @@ # 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 + + it 'spots B-A vs C-B asymmetry in five-field forms' do + + expect(Rufus::Scheduler::CronLine.new( + '10,17,30 * * * *').brute_frequency).to eq(7 * 60) + expect(Rufus::Scheduler::CronLine.new( + '10,23,30 * * * *').brute_frequency).to eq(7 * 60) + end + + it 'spots B-A vs C-B asymmetry in six-field forms' do + + expect(Rufus::Scheduler::CronLine.new( + '10,17,30 * * * * *').brute_frequency).to eq(7) + expect(Rufus::Scheduler::CronLine.new( + '10,23,30 * * * * *').brute_frequency).to eq(7) + end + + it 'handles crontab modulo syntax in five-field forms' do + + expect(Rufus::Scheduler::CronLine.new( + '*/10 * * * *').brute_frequency).to eq(10 * 60) + expect(Rufus::Scheduler::CronLine.new( + '* */10 * * *').brute_frequency).to eq(60) # "*" all minutes [0..59] + expect(Rufus::Scheduler::CronLine.new( + '0 */10 * * *').brute_frequency).to eq(4 * 60 * 60) # 2000 to 0000 + end + + it 'handles crontab modulo syntax in six-field forms' do + + expect(Rufus::Scheduler::CronLine.new( + '*/10 * * * * *').brute_frequency).to eq(10) + expect(Rufus::Scheduler::CronLine.new( + '* */10 * * * *').brute_frequency).to eq(1) # "*" all seconds [0..59] + expect(Rufus::Scheduler::CronLine.new( + '0 */10 * * * *').brute_frequency).to eq(10 * 60) end end context 'summer time' do