forked from ice-cube-ruby/ice_cube
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Occurrence class to handle end_time
Issue ice-cube-ruby#119
- Loading branch information
Showing
4 changed files
with
174 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|