Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' into issue53

  • Loading branch information...
commit af3e2f1c8ad2b769cdb9b48d4e64c76d01afd4ed 2 parents f4ee537 + 933e0bc
@seejohnrun authored
View
7 CHANGELOG
@@ -64,3 +64,10 @@
0.7.5
* Fix an issue with occurrences_between when using count [#54]
+
+0.7.6
+ * Support for #terminating? and #conflicts_with?
+
+---
+
+* Added "Weekends" and "Weekdays" to #day's to_s
View
2  README.md
@@ -248,7 +248,7 @@ Use the GitHub issue tracker
(The MIT License)
-Copyright © 2010 John Crepezzi
+Copyright © 2010-2012 John Crepezzi
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
View
47 lib/ice_cube/schedule.rb
@@ -125,9 +125,7 @@ def occurrences(closing_time)
# All of the occurrences
def all_occurrences
- unless end_time || recurrence_rules.all?(&:terminating?)
- raise ArgumentError.new('Rule must specify either an until date or a count to use #all_occurrences')
- end
+ raise ArgumentError.new('Rule must specify either an until date or a count to use #all_occurrences') unless terminating?
find_occurrences(start_time)
end
@@ -180,6 +178,43 @@ def occurring_at?(time)
end
end
+ # Determine if this schedule conflicts with another schedule
+ # @param [IceCube::Schedule] other_schedule - The schedule to compare to
+ # @param [Time] closing_time - the last time to consider
+ # @return [Boolean] whether or not the schedules conflict at all
+ def conflicts_with?(other_schedule, closing_time = nil)
+ unless terminating? || other_schedule.terminating? || closing_time
+ raise ArgumentError.new 'At least one schedule must be terminating to use #conflicts_with?'
+ end
+ # Pick the terminating schedule, and other schedule
+ # No need to reverse if terminating? or there is a closing time
+ terminating_schedule = self
+ unless terminating? || closing_time
+ terminating_schedule, other_schedule = other_schedule, terminating_schedule
+ end
+ # Go through each occurrence of the terminating schedule and determine
+ # if the other occurs at that time
+ last_time = nil
+ terminating_schedule.each_occurrence do |time|
+ if closing_time && time > closing_time
+ last_time = closing_time
+ break
+ end
+ last_time = time
+ return true if other_schedule.occurring_at?(time)
+ end
+ # Due to durations, we need to walk up to the end time, and verify in the
+ # other direction
+ if last_time
+ other_schedule.each_occurrence do |time|
+ break if time > last_time
+ return true if terminating_schedule.occurring_at?(time)
+ end
+ end
+ # No conflict, return false
+ false
+ end
+
# Determine if the schedule occurs at a specific time
def occurs_at?(time)
occurs_between?(time, time)
@@ -261,6 +296,12 @@ def self.from_hash(data, options = {})
schedule
end
+ # Determine if the schedule will end
+ # @return [Boolean] true if ending, false if repeating forever
+ def terminating?
+ end_time || recurrence_rules.all?(&:terminating?)
+ end
+
private
# Reset all rules for another run
View
16 lib/ice_cube/validations/day.rb
@@ -25,7 +25,7 @@ def initialize(day)
end
def build_s(builder)
- builder.piece(:day) << "#{Date::DAYNAMES[day]}s"
+ builder.piece(:day) << day
end
def build_hash(builder)
@@ -44,8 +44,18 @@ def type
:wday
end
- StringBuilder.register_formatter(:day) do |segments|
- "on #{StringBuilder.sentence(segments)}"
+ StringBuilder.register_formatter(:day) do |validation_days|
+ # sort the days
+ validation_days.sort!
+ # pick the right shortening, if applicable
+ if validation_days == [0, 6]
+ 'on Weekends'
+ elsif validation_days == (1..5).to_a
+ 'on Weekdays'
+ else
+ segments = validation_days.map { |d| "#{Date::DAYNAMES[d]}s" }
+ "on #{StringBuilder.sentence(segments)}"
+ end
end
end
View
2  lib/ice_cube/version.rb
@@ -1,5 +1,5 @@
module IceCube
- VERSION = '0.7.5'
+ VERSION = '0.7.6'
end
View
3  spec/examples/ice_cube_spec.rb
@@ -622,7 +622,8 @@
end
it 'should be able to work with occurs_on? at an odd time - start of day' do
- schedule = IceCube::Schedule.new(Time.local(2010, 8, 10, 0, 0, 0))
+ Time.zone = 'Eastern Time (US & Canada)'
+ schedule = IceCube::Schedule.new(Time.zone.local(2010, 8, 10, 0, 0, 0))
schedule.add_recurrence_rule IceCube::Rule.weekly
schedule.occurs_on?(Date.new(2010, 8, 10)).should be(true)
schedule.occurs_on?(Date.new(2010, 8, 11)).should be(false)
View
97 spec/examples/schedule_spec.rb
@@ -4,6 +4,103 @@
include IceCube
+ describe :conflicts_with? do
+
+ it 'should raise an error if both are not terminating' do
+ schedules = 2.times.map do
+ schedule = IceCube::Schedule.new(Time.now)
+ schedule.rrule IceCube::Rule.daily
+ schedule
+ end
+ lambda do
+ schedules.first.conflicts_with?(schedules.last)
+ end.should raise_error ArgumentError
+ end
+
+ it 'should not raise error if both are non-terminating closing time present' do
+ schedule1 = IceCube::Schedule.new Time.now
+ schedule1.rrule IceCube::Rule.weekly
+ schedule2 = IceCube::Schedule.new Time.now
+ schedule2.rrule IceCube::Rule.weekly
+ lambda do
+ schedule1.conflicts_with?(schedule2, Time.now + IceCube::ONE_DAY)
+ end.should_not raise_error
+ end
+
+ it 'should not raise an error if one is non-terminating' do
+ schedule1 = IceCube::Schedule.new Time.now
+ schedule1.rrule IceCube::Rule.weekly
+ schedule2 = IceCube::Schedule.new Time.now
+ schedule2.rrule IceCube::Rule.weekly.until(Time.now)
+ lambda do
+ schedule1.conflicts_with?(schedule2)
+ end.should_not raise_error
+ end
+
+ it 'should not raise an error if the other is non-terminating' do
+ schedule1 = IceCube::Schedule.new Time.now
+ schedule1.rrule IceCube::Rule.weekly.until(Time.now)
+ schedule2 = IceCube::Schedule.new Time.now
+ schedule2.rrule IceCube::Rule.weekly
+ lambda do
+ schedule1.conflicts_with?(schedule2)
+ end.should_not raise_error
+ end
+
+ it 'should return true if conflict is present' do
+ start_time = Time.now
+ schedule1 = IceCube::Schedule.new(start_time)
+ schedule1.rrule IceCube::Rule.daily
+ schedule2 = IceCube::Schedule.new(start_time)
+ schedule2.rrule IceCube::Rule.daily
+ conflict = schedule1.conflicts_with?(schedule2, start_time + IceCube::ONE_DAY)
+ conflict.should be_true
+ end
+
+ it 'should return false if conflict is not present' do
+ start_time = Time.now
+ schedule1 = IceCube::Schedule.new(start_time)
+ schedule1.rrule IceCube::Rule.weekly.day(:tuesday)
+ schedule2 = IceCube::Schedule.new(start_time)
+ schedule2.rrule IceCube::Rule.weekly.day(:monday)
+ conflict = schedule1.conflicts_with?(schedule2, start_time + IceCube::ONE_DAY)
+ conflict.should be_false
+ end
+
+ it 'should return true if conflict is present based on duration' do
+ start_time = Time.now
+ schedule1 = IceCube::Schedule.new(start_time, :duration => IceCube::ONE_DAY + 1)
+ schedule1.rrule IceCube::Rule.weekly.day(:monday)
+ schedule2 = IceCube::Schedule.new(start_time)
+ schedule2.rrule IceCube::Rule.weekly.day(:tuesday)
+ conflict = schedule1.conflicts_with?(schedule2, start_time + IceCube::ONE_WEEK)
+ conflict.should be_true
+ end
+
+ it 'should return true if conflict is present based on duration - other way' do
+ start_time = Time.now
+ schedule1 = IceCube::Schedule.new(start_time)
+ schedule1.rrule IceCube::Rule.weekly.day(:tuesday)
+ schedule2 = IceCube::Schedule.new(start_time, :duration => IceCube::ONE_DAY + 1)
+ schedule2.rrule IceCube::Rule.weekly.day(:monday)
+ conflict = schedule1.conflicts_with?(schedule2, start_time + IceCube::ONE_WEEK)
+ conflict.should be_true
+ end
+
+ it 'should return false if conflict is past closing_time' do
+ start_time = Time.local(2011, 1, 1, 12) # Sunday
+ schedule1 = IceCube::Schedule.new(start_time)
+ schedule1.rrule IceCube::Rule.weekly.day(:friday)
+ schedule2 = IceCube::Schedule.new(start_time)
+ schedule2.rrule IceCube::Rule.weekly.day(:friday)
+ schedule2.conflicts_with?(schedule1, start_time + IceCube::ONE_WEEK).
+ should be_true
+ schedule2.conflicts_with?(schedule1, start_time + IceCube::ONE_DAY).
+ should be_false
+ end
+
+ end
+
describe :each do
it 'should be able to yield occurrences for a schedule' do
View
28 spec/examples/to_s_spec.rb
@@ -44,6 +44,34 @@
IceCube::Rule.weekly.day(:monday, :tuesday, :wednesday).to_s.should == 'Weekly on Mondays, Tuesdays, and Wednesdays'
end
+ it 'should show saturday and sunday as weekends' do
+ IceCube::Rule.weekly.day(:saturday, :sunday).to_s.should == 'Weekly on Weekends'
+ end
+
+ it 'should not show saturday and sunday as weekends when other days are present also' do
+ IceCube::Rule.weekly.day(:sunday, :monday, :saturday).to_s.should ==
+ 'Weekly on Sundays, Mondays, and Saturdays'
+ end
+
+ it 'should reorganize days to be in order' do
+ IceCube::Rule.weekly.day(:tuesday, :monday).to_s.should ==
+ 'Weekly on Mondays and Tuesdays'
+ end
+
+ it 'should show weekdays as such' do
+ IceCube::Rule.weekly.day(
+ :monday, :tuesday, :wednesday,
+ :thursday, :friday
+ ).to_s.should == 'Weekly on Weekdays'
+ end
+
+ it 'should not show weekdays as such when a weekend day is present' do
+ IceCube::Rule.weekly.day(
+ :sunday, :monday, :tuesday, :wednesday,
+ :thursday, :friday
+ ).to_s.should == 'Weekly on Sundays, Mondays, Tuesdays, Wednesdays, Thursdays, and Fridays'
+ end
+
it 'should work with a single date' do
schedule = IceCube::Schedule.new Time.local(2010, 3, 20)
schedule.add_recurrence_date Time.local(2010, 3, 20)
Please sign in to comment.
Something went wrong with that request. Please try again.