mirror of
https://github.com/plashchynski/crono.git
synced 2026-03-29 05:42:02 +02:00
Added 'on' option for Period
This commit is contained in:
@@ -1,19 +1,20 @@
|
|||||||
module Crono
|
module Crono
|
||||||
# Period describe frequency of performing a task
|
# Period describe frequency of performing a task
|
||||||
class Period
|
class Period
|
||||||
def initialize(period, at: nil)
|
DAYS = [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday,
|
||||||
|
:sunday]
|
||||||
|
|
||||||
|
def initialize(period, at: nil, on: nil)
|
||||||
@period = period
|
@period = period
|
||||||
@at_hour, @at_min = parse_at(at) if at
|
@at_hour, @at_min = parse_at(at) if at
|
||||||
|
@on = parse_on(on) if on
|
||||||
end
|
end
|
||||||
|
|
||||||
def next(since: nil)
|
def next(since: nil)
|
||||||
if since.nil?
|
return initial_next unless since
|
||||||
@next = Time.now.change(time_atts)
|
@next = @period.since(since)
|
||||||
return @next if @next.future?
|
@next = @next.beginning_of_week.advance(days: @on) if @on
|
||||||
since = Time.now
|
@next.change(time_atts)
|
||||||
end
|
|
||||||
|
|
||||||
@period.since(since).change(time_atts)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def description
|
def description
|
||||||
@@ -22,6 +23,28 @@ module Crono
|
|||||||
desc
|
desc
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def initial_next
|
||||||
|
next_time = initial_day.change(time_atts)
|
||||||
|
return next_time if next_time.future?
|
||||||
|
@period.from_now.change(time_atts)
|
||||||
|
end
|
||||||
|
|
||||||
|
def initial_day
|
||||||
|
return Time.now unless @on
|
||||||
|
day = Time.now.beginning_of_week.advance(days: @on)
|
||||||
|
return day if day.future?
|
||||||
|
@period.from_now.beginning_of_week.advance(days: @on)
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_on(on)
|
||||||
|
day_number = DAYS.index(on)
|
||||||
|
fail "Wrong 'on' day" unless day_number
|
||||||
|
fail "period should be at least 1 week to use 'on'" if @period < 1.week
|
||||||
|
day_number
|
||||||
|
end
|
||||||
|
|
||||||
def parse_at(at)
|
def parse_at(at)
|
||||||
case at
|
case at
|
||||||
when String
|
when String
|
||||||
@@ -34,8 +57,6 @@ module Crono
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def time_atts
|
def time_atts
|
||||||
{ hour: @at_hour, min: @at_min }.compact
|
{ hour: @at_hour, min: @at_min }.compact
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -15,6 +15,43 @@ describe Crono::Period do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe '#next' do
|
describe '#next' do
|
||||||
|
context 'in weakly basis' do
|
||||||
|
it "should raise error if 'on' is wrong" do
|
||||||
|
expect { @period = Crono::Period.new(7.days, on: :bad_day) }
|
||||||
|
.to raise_error("Wrong 'on' day")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should raise error when period is less than 1 week' do
|
||||||
|
expect { @period = Crono::Period.new(6.days, on: :monday) }
|
||||||
|
.to raise_error("period should be at least 1 week to use 'on'")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return a 'on' day" do
|
||||||
|
@period = Crono::Period.new(1.week, on: :thursday, at: '15:30')
|
||||||
|
current_week = Time.now.beginning_of_week
|
||||||
|
last_run_time = current_week.advance(days: 1) # last run on the tuesday
|
||||||
|
next_run_at = Time.now.next_week.advance(days: 3)
|
||||||
|
.change(hour: 15, min: 30)
|
||||||
|
expect(@period.next(since: last_run_time)).to be_eql(next_run_at)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return a next week day 'on'" do
|
||||||
|
@period = Crono::Period.new(1.week, on: :thursday)
|
||||||
|
Timecop.freeze(Time.now.beginning_of_week.advance(days: 4)) do
|
||||||
|
expect(@period.next).to be_eql(Time.now.next_week.advance(days: 3))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should return a current week day on the first run if not too late' do
|
||||||
|
@period = Crono::Period.new(7.days, on: :tuesday)
|
||||||
|
beginning_of_the_week = Time.now.beginning_of_week
|
||||||
|
tuesday = beginning_of_the_week.advance(days: 1)
|
||||||
|
Timecop.freeze(beginning_of_the_week) do
|
||||||
|
expect(@period.next).to be_eql(tuesday)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'in daily basis' do
|
context 'in daily basis' do
|
||||||
it 'should return the time 2 days from now' do
|
it 'should return the time 2 days from now' do
|
||||||
@period = Crono::Period.new(2.day)
|
@period = Crono::Period.new(2.day)
|
||||||
|
|||||||
Reference in New Issue
Block a user