Skip to content
Browse files

Merge pull request #12 from nbibler/through

Add a :through option for event generation limitation
  • Loading branch information...
2 parents 001c9ec + 98a3ddf commit 6e500b16d7675fffbbb1ec971f38dc73e595db82 @fnando committed Nov 17, 2011
Showing with 137 additions and 3 deletions.
  1. +6 −0 README.rdoc
  2. +1 −0 lib/recurrence/event/base.rb
  3. +5 −3 lib/recurrence/namespace.rb
  4. +125 −0 spec/recurrence_spec.rb
View
6 README.rdoc
@@ -59,6 +59,11 @@ A simple library to handle recurring events.
r = Recurrence.new(:every => :day, :until => '2010-01-31')
r = Recurrence.new(:every => :day, :starts => Date.today, :until => '2010-01-31')
+ # Generate a collection of events which always includes a final event with the given through date
+ # :through defaults to being unset
+ r = Recurrence.new(:every => :day, :through => '2010-01-31')
+ r = Recurrence.new(:every => :day, :starts => Date.today, :through => '2010-01-31')
+
# Override the next date handler
r = Recurrence.new(:every => :month, :on => 1, :handler => Proc.new { |day, month, year| raise("Date not allowed!") if year == 2011 && month == 12 && day == 31 })
@@ -70,6 +75,7 @@ A simple library to handle recurring events.
r.events!.each {|date| puts date.to_s } # => reset items cache and re-execute it
r.events(:starts => '2009-01-01').each {|date| puts date.to_s }
r.events(:until => '2009-01-10').each {|date| puts date.to_s }
+ r.events(:through => '2009-01-10').each {|date| puts date.to_s }
r.events(:starts => '2009-01-05', :until => '2009-01-10').each {|date| puts date.to_s }
# Iterating events
View
1 lib/recurrence/event/base.rb
@@ -35,6 +35,7 @@ def next!
@date = next_in_recurrence
+ @finished = true if @options[:through] && @date >= @options[:through]
@finished, @date = true, nil if @date > @options[:until]
shift_to @date if @date && @options[:shift]
@date
View
8 lib/recurrence/namespace.rb
@@ -224,9 +224,10 @@ def next!
def events(options={})
options[:starts] = as_date(options[:starts])
options[:until] = as_date(options[:until])
+ options[:through] = as_date(options[:through])
options[:repeat] ||= @options[:repeat]
- reset! if options[:starts] || options[:until]
+ reset! if options[:starts] || options[:until] || options[:through]
@events ||= Array.new.tap do |list|
loop do
@@ -240,8 +241,9 @@ def events(options={})
stop_repeat = options[:repeat] && list.size == options[:repeat]
stop_until = options[:until] && options[:until] <= date
+ stop_through = options[:through] && options[:through] <= date
- break if stop_until || stop_repeat
+ break if stop_until || stop_repeat || stop_through
end
end
end
@@ -282,7 +284,7 @@ def each!(&block)
private
def initialize_dates(options) # :nodoc:
- [:starts, :until].each do |name|
+ [:starts, :until, :through].each do |name|
options[name] = as_date(options[name])
end
View
125 spec/recurrence_spec.rb
@@ -107,6 +107,12 @@
@recurrence.events[-1].should == date.to_date
end
+ it "should recur through 1 month from now" do
+ date = 1.month.from_now
+ @recurrence = recurrence(:every => :day, :through => date.to_date)
+ @recurrence.events[-1].should == date.to_date
+ end
+
it "should start 2 months ago (#{2.months.ago.to_s(:date)})" do
date = 2.months.ago
@recurrence = recurrence(:every => :day, :starts => date.to_date)
@@ -122,6 +128,13 @@
@recurrence.events[-1].to_s.should == "2008-04-24"
end
+ it "should start at 2008-03-19 and repeat through 2008-04-24" do
+ @recurrence = recurrence(:every => :day, :starts => "2008-03-19", :through => "2008-04-24")
+ @recurrence.events[0].to_s.should == "2008-03-19"
+ @recurrence.events[1].to_s.should == "2008-03-20"
+ @recurrence.events[-1].to_s.should == "2008-04-24"
+ end
+
it "should use interval" do
@recurrence = recurrence(:every => :day, :interval => 2, :starts => "2008-09-21")
@recurrence.events[0].to_s.should == "2008-09-21"
@@ -143,6 +156,16 @@
)
@recurrence.events[-1].to_s.should == "2008-04-24"
end
+
+ it "should not have a lacking day if the interval does not match the last day" do
+ @recurrence = recurrence(
+ :every => :day,
+ :starts => "2008-03-19",
+ :through => "2008-04-25",
+ :interval => 2
+ )
+ @recurrence.events[-1].to_s.should == "2008-04-26"
+ end
end
context "with weekly recurring" do
@@ -157,6 +180,12 @@
@recurrence.events[-1].should == date.to_date
end
+ it "should repeat through 6 weeks from now" do
+ date = 6.weeks.from_now
+ @recurrence = recurrence(:every => :week, :on => date.wday, :through => date.to_date)
+ @recurrence.events[-1].should == date.to_date
+ end
+
it "should start 3 months ago (#{3.months.ago.to_s(:date)})" do
date = 3.months.ago
@@ -185,6 +214,21 @@
@recurrence.events[-1].to_s.should == ends.to_s
end
+ it "should start at 2008-02-29 and repeat through 2008-03-14" do
+ starts = Date.parse("2008-02-29")
+ ends = Date.parse("2008-03-14")
+
+ @recurrence = recurrence(
+ :every => :week,
+ :on => :friday,
+ :starts => starts,
+ :through=> ends.to_date
+ )
+ @recurrence.events[0].to_s.should == "2008-02-29"
+ @recurrence.events[1].to_s.should == "2008-03-07"
+ @recurrence.events[-1].to_s.should == ends.to_s
+ end
+
it "should use interval" do
starts = Date.parse("2008-09-21")
@recurrence = recurrence(
@@ -273,6 +317,12 @@
@recurrence.events[-1].should == date.to_date
end
+ it "should repeat through 8 months from now" do
+ date = 8.months.from_now
+ @recurrence = recurrence(:every => :month, :on => date.day, :through => date.to_date)
+ @recurrence.events[-1].should == date.to_date
+ end
+
it "should start 9 months ago" do
date = 9.months.ago
@@ -294,6 +344,20 @@
@recurrence.events[-1].to_s.should == "2008-11-07"
end
+ it "should start at 2008-06-07 and repeat through 2008-11-07" do
+ starts = Date.parse("2008-06-07")
+ ends = Date.parse("2008-11-07")
+
+ @recurrence = recurrence(
+ :every => :month,
+ :on => starts.day,
+ :starts => starts,
+ :through=> ends
+ )
+ @recurrence.events[0].to_s.should == "2008-06-07"
+ @recurrence.events[-1].to_s.should == "2008-11-07"
+ end
+
it "should run until next available 27th" do
starts = Date.parse("2008-09-28")
@@ -306,6 +370,18 @@
@recurrence.events[0].to_s.should == "2008-10-27"
end
+ it "should run through final available 27th" do
+ starts = Date.parse("2008-09-28")
+
+ @recurrence = recurrence(
+ :every => :month,
+ :on => 27,
+ :starts => starts,
+ :through=> "2009-01-01"
+ )
+ @recurrence.events[-1].to_s.should == "2009-01-27"
+ end
+
it "should use interval" do
starts = Date.parse("2008-01-31")
@recurrence = recurrence(
@@ -388,6 +464,18 @@
@recurrence.events[-1].should == date.to_date
end
+ it "should repeat through 8 months from now" do
+ date = 8.months.from_now
+ week = (date.day - 1) / 7 + 1
+ @recurrence = recurrence(
+ :every => :month,
+ :on => week,
+ :weekday => date.wday,
+ :through => date.to_date
+ )
+ @recurrence.events[-1].should == date.to_date
+ end
+
it "should start 9 months ago" do
date = 9.months.ago
week = (date.day - 1) / 7 + 1
@@ -533,6 +621,16 @@
@recurrence.events[-1].should == date.to_date
end
+ it "should repeat through 7 years from now" do
+ date = 7.years.from_now
+ @recurrence = recurrence(
+ :every => :year,
+ :on => [date.month, date.day],
+ :through => date.to_date
+ )
+ @recurrence.events[-1].should == date.to_date
+ end
+
it "should start 2 years ago" do
date = 2.years.ago
@recurrence = recurrence(
@@ -557,6 +655,20 @@
@recurrence.events[-1].to_s.should == "2018-06-07"
end
+ it "should start at 2003-06-07 and repeat through 2018-06-07" do
+ starts = Date.parse("2003-06-07")
+ ends = Date.parse("2018-06-07")
+
+ @recurrence = recurrence(
+ :every => :year,
+ :on => [starts.month, starts.day],
+ :starts => starts,
+ :through=> ends
+ )
+ @recurrence.events[0].to_s.should == "2003-06-07"
+ @recurrence.events[-1].to_s.should == "2018-06-07"
+ end
+
it "should use interval" do
starts = Date.parse("2008-09-21")
@@ -584,6 +696,19 @@
@recurrence.events.size.should == 5
end
+ it "should include the through date when less than a perfect interval" do
+ starts = Date.parse("2003-06-07")
+ ends = Date.parse("2018-07-12")
+
+ @recurrence = recurrence(
+ :every => :year,
+ :on => [starts.month, starts.day],
+ :starts => starts,
+ :through => ends
+ )
+ @recurrence.events[-1].to_s.should == '2019-06-07'
+ end
+
it "should run until next available date when chosen settings are greater than start date" do
starts = Date.parse("2008-09-03")

0 comments on commit 6e500b1

Please sign in to comment.
Something went wrong with that request. Please try again.