Skip to content

Commit

Permalink
Add Occurrence class to handle end_time
Browse files Browse the repository at this point in the history
  • Loading branch information
avit committed Dec 21, 2012
1 parent 075208b commit 57862cf
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/ice_cube.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module IceCube

autoload :Rule, 'ice_cube/rule'
autoload :Schedule, 'ice_cube/schedule'
autoload :Occurrence, 'ice_cube/occurrence'

autoload :IcalBuilder, 'ice_cube/builders/ical_builder'
autoload :HashBuilder, 'ice_cube/builders/hash_builder'
Expand Down
64 changes: 64 additions & 0 deletions lib/ice_cube/occurrence.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
require 'forwardable'
require 'delegate'

module IceCube

class Occurrence < SimpleDelegator

# Optimize for common methods to avoid method_missing
extend Forwardable
def_delegators :start_time, :to_s, :to_i, :<=>, :==
def_delegators :to_range, :cover?, :include?, :each, :first, :last

attr_reader :start_time, :end_time

def initialize(start_time, end_time=nil)
@start_time = start_time
@end_time = end_time || start_time
__setobj__ @start_time
end

def intersects? other
if other.is_a?(Occurrence) || other.is_a?(Range)
lower_bound_1 = first + 1
upper_bound_1 = last # exclude end
lower_bound_2 = other.first + 1
upper_bound_2 = other.last + 1
if (lower_bound_2 <=> upper_bound_2) > 0
false
elsif (lower_bound_1 <=> upper_bound_1) > 0
false
else
(upper_bound_1 <=> lower_bound_2) >= 0 and
(upper_bound_2 <=> lower_bound_1) >= 0
end
else
cover? other
end
end

def comparable_time
start_time
end

def duration
end_time - start_time
end

def to_range
start_time..end_time
end

def to_time
@start_time
end

def to_s
if duration > 0
"#{start_time} - #{end_time}"
else
"#{start_time}"
end
end
end
end
12 changes: 12 additions & 0 deletions spec/examples/active_support_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,15 @@
end

end

describe IceCube::Occurrence do

it 'can be subtracted from a time' do
start_time = Time.now
occurrence = Occurrence.new(start_time)

difference = (start_time + 60) - occurrence
difference.should == 60
end

end
97 changes: 97 additions & 0 deletions spec/examples/occurrence_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
require File.dirname(__FILE__) + '/../spec_helper'

include IceCube

describe Occurrence do

describe :to_s do
it "looks like a Time for a zero duration" do
start_time = Time.now
occurrence = Occurrence.new(start_time)

occurrence.to_s.should == start_time.to_s
end

it "looks like a range for a non-zero duration" do
start_time = Time.now
end_time = start_time + ONE_HOUR
occurrence = Occurrence.new(start_time, end_time)

occurrence.to_s.should == "#{start_time} - #{end_time}"
end
end

describe :end_time do

it 'defaults to start_time' do
start_time = Time.now
occurrence = Occurrence.new(start_time)

occurrence.end_time.should == start_time
end

it 'returns specified end_time' do
start_time = Time.now
end_time = start_time + 3600
occurrence = Occurrence.new(start_time, end_time)

occurrence.end_time.should == end_time
end

end

describe :arithmetic do

let(:start_time) { Time.now }
let(:occurrence) { Occurrence.new(start_time) }

it 'returns a time when adding' do
new_time = occurrence + 60
new_time.should == start_time + 60
end

it 'can get difference from a time' do
difference = occurrence - (start_time - 60)
difference.should == 60
end

end

describe :intersects? do

let(:start_time) { Time.now }
let(:end_time) { start_time + 3600 }

it 'is true for a time during the occurrence' do
occurrence = Occurrence.new(start_time, end_time)

inclusion = occurrence.intersects? start_time + 1800
inclusion.should be_true
end

it 'is false for a time outside the occurrence' do
occurrence = Occurrence.new(start_time, end_time)

inclusion = occurrence.intersects? start_time + 3601
inclusion.should be_false
end

it 'is true for an intersecting occurrence' do
occurrence1 = Occurrence.new(start_time, end_time)
occurrence2 = Occurrence.new(start_time + 1, end_time + 1)

inclusion = occurrence1.intersects? occurrence2
inclusion.should be_true
end

it 'is false for a non-intersecting occurrence' do
occurrence1 = Occurrence.new(start_time, end_time)
occurrence2 = Occurrence.new(end_time)

inclusion = occurrence1.intersects? occurrence2
inclusion.should be_false
end
end

end

0 comments on commit 57862cf

Please sign in to comment.