spec/timeframe_spec.rb in timeframe-0.0.1 vs spec/timeframe_spec.rb in timeframe-0.0.2
- old
+ new
@@ -1,248 +1,270 @@
-require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
-require 'date'
-
-describe Timeframe do
- describe 'initialization' do
- it 'should create a timeframe using date strings' do
- tf = Timeframe.new('2008-02-14', '2008-05-10')
- tf.from.should == Date.parse('2008-02-14')
- tf.to.should == Date.parse('2008-05-10')
- end
- it 'should create a timeframe using date objects' do
- start = Date.parse('2008-02-14')
- finish = Date.parse('2008-05-10')
- tf = Timeframe.new(start, finish)
- tf.from.should == start
- tf.to.should == finish
- end
- it "should accept months" do
- timeframe = Timeframe.new(:month => 1)
- timeframe.from.should == Date.today.change(:month => 1, :day => 1)
- timeframe.to.should == Date.today.change(:month => 2, :day => 1)
- end
- it "should accept month names" do
- timeframe = Timeframe.new(:month => 'february')
- timeframe.from.should == Date.today.change(:month => 2, :day => 1)
- timeframe.to.should == Date.today.change(:month => 3, :day => 1)
- end
- it "should accept years" do
- timeframe = Timeframe.new(:year => 2004)
- timeframe.from.should == Date.new(2004, 1, 1)
- timeframe.to.should == Date.new(2005, 1, 1)
- end
- it "should accept years and months" do
- timeframe = Timeframe.new(:year => 2005, :month => 5)
- timeframe.from.should == Date.new(2005, 5, 1)
- timeframe.to.should == Date.new(2005, 6, 1)
- end
- it "should not accept just one date argument" do
- lambda {
- Timeframe.new Date.new(2007, 2, 1)
- }.should raise_error(ArgumentError, /supply/)
- end
- it "should not accept end date that is earlier than start date" do
- lambda {
- timeframe = Timeframe.new Date.new(2008, 1, 1), Date.new(2007, 1, 1)
- }.should raise_error(ArgumentError, /earlier/)
- end
- it "should not accept timeframes that cross year boundaries" do
- lambda {
- timeframe = Timeframe.new Date.new(2007, 1, 1), Date.new(2008, 1, 2)
- }.should raise_error(ArgumentError, /cross/)
- end
- it "should optionally accept timeframes that cross year boundaries" do
- lambda {
- timeframe = Timeframe.new Date.new(2007, 1, 1), Date.new(2008, 1, 2), :skip_year_boundary_crossing_check => true
- }.should_not raise_error
- end
- end
-
- describe '#inspect' do
- it 'should return the time frame in readable text' do
- start = Date.parse('2008-02-14')
- finish = Date.parse('2008-05-10')
- tf = Timeframe.new(start, finish)
- tf.inspect.should =~ /<Timeframe\(-?\d+\) 86 days starting 2008-02-14 ending 2008-05-10>/
- end
- end
-
- describe '.constrained_new' do
- let(:start) { Date.parse('2008-02-14') }
- let(:finish) { Date.parse('2008-05-10') }
- let(:constraint_start) { Date.parse('2008-01-01') }
- let(:constraint_finish) { Date.parse('2008-12-01') }
- let(:constraint) { Timeframe.new(constraint_start, constraint_finish) }
-
- it "should allow for constrained creation" do
- constraint = Timeframe.new :year => 2008
- may = Timeframe.new Date.new(2008,5,1), Date.new(2008,6,1)
- january = Timeframe.new Date.new(2008,1,1), Date.new(2008,2,1)
- Timeframe.constrained_new(may.from, may.to, constraint).should == may
- Timeframe.constrained_new(Date.new(2007,1,1), Date.new(2010,1,1), constraint).should == constraint
- Timeframe.constrained_new(Date.new(2007,11,1), Date.new(2008,2,1), constraint).should == january
- end
- it 'should return a timeframe spanning start and end date if within constraint' do
- tf = Timeframe.constrained_new(start, finish, constraint)
- tf.from.should == start
- tf.to.should == finish
- end
- it 'should return a timeframe spanning constraint start and end date if outside constraint' do
- constraint = Timeframe.new(start, finish)
- tf = Timeframe.constrained_new(constraint_start, constraint_finish, constraint)
- tf.from.should == start
- tf.to.should == finish
- end
- it 'should return a timeframe starting at constraint start' do
- start = Date.parse('2008-01-01')
- constraint_start = Date.parse('2008-01-14')
- constraint = Timeframe.new(constraint_start, constraint_finish)
- tf = Timeframe.constrained_new(start, finish, constraint)
- tf.from.should == constraint_start
- tf.to.should == finish
- end
- it 'should return a timeframe ending at constraint end' do
- constraint_finish = Date.parse('2008-04-14')
- constraint = Timeframe.new(constraint_start, constraint_finish)
- tf = Timeframe.constrained_new(start, finish, constraint)
- tf.from.should == start
- tf.to.should == constraint_finish
- end
- it "should return a 0-length timeframe when constraining a timeframe by a disjoint timeframe" do
- constraint = Timeframe.new :year => 2010
- timeframe = Timeframe.constrained_new(
- Date.new(2009,1,1), Date.new(2010,1,1), constraint)
- timeframe.days.should == 0
- end
- end
-
- describe '.this_year' do
- it "should return the current year" do
- Timeframe.this_year.should == Timeframe.new(:year => Time.now.year)
- end
- end
-
- describe '#days' do
- it "should return them number of days included" do
- #TODO: make these separate "it" blocks, per best practices
- Timeframe.new(Date.new(2007, 1, 1), Date.new(2008, 1, 1)).days.should == 365
- Timeframe.new(Date.new(2008, 1, 1), Date.new(2009, 1, 1)).days.should == 366 #leap year
- Timeframe.new(Date.new(2007, 11, 1), Date.new(2007, 12, 1)).days.should == 30
- Timeframe.new(Date.new(2007, 11, 1), Date.new(2008, 1, 1)).days.should == 61
- Timeframe.new(Date.new(2007, 2, 1), Date.new(2007, 3, 1)).days.should == 28
- Timeframe.new(Date.new(2008, 2, 1), Date.new(2008, 3, 1)).days.should == 29
- Timeframe.new(Date.new(2008, 2, 1), Date.new(2008, 2, 1)).days.should == 0
- end
- end
-
- describe '#include?' do
- it "should know if a certain date is included in the Timeframe" do
- #TODO: make these separate "it" blocks, per best practices
- timeframe = Timeframe.new :year => 2008, :month => 2
- [
- Date.new(2008, 2, 1),
- Date.new(2008, 2, 5),
- Date.new(2008, 2, 29)
- ].each do |date|
- timeframe.include?(date).should == true
- end
- [
- Date.new(2008, 1, 1),
- Date.new(2007, 2, 1),
- Date.new(2008, 3, 1)
- ].each do |date|
- timeframe.include?(date).should == false
- end
- end
- end
-
- describe '#==' do
- it "should be able to know if it's equal to another Timeframe object" do
- Timeframe.new(:year => 2007).should == Timeframe.new(:year => 2007)
- Timeframe.new(:year => 2004, :month => 1).should == Timeframe.new(:year => 2004, :month => 1)
- end
-
- it "should hash equal hash values when the timeframe is equal" do
- Timeframe.new(:year => 2007).hash.should == Timeframe.new(:year => 2007).hash
- Timeframe.new(:year => 2004, :month => 1).hash.should == Timeframe.new(:year => 2004, :month => 1).hash
- end
- end
-
- describe '#months' do
- it "should return an array of month-long subtimeframes" do
- Timeframe.new(:year => 2009).months.length.should == 12
- end
- it "should not return an array of month-long subtimeframes if provided an inappropriate range" do
- lambda {
- Timeframe.new(Date.new(2009, 3, 2), Date.new(2009, 3, 5)).months
- }.should raise_error(ArgumentError, /whole/)
- lambda {
- Timeframe.new(Date.new(2009, 1, 1), Date.new(2012, 1, 1), :skip_year_boundary_crossing_check => true).months
- }.should raise_error(ArgumentError, /dangerous during/)
- end
- end
-
- describe '#year' do
- it "should return the relevant year of a timeframe" do
- Timeframe.new(Date.new(2009, 2, 1), Date.new(2009, 4, 1)).year.should == Timeframe.new(:year => 2009)
- end
- it "should not return the relevant year of a timeframe if provided an inappropriate range" do
- lambda {
- Timeframe.new(Date.new(2009, 1, 1), Date.new(2012, 1, 1), :skip_year_boundary_crossing_check => true).year
- }.should raise_error(ArgumentError, /dangerous during/)
- end
- end
-
- describe '#&' do
- it "should return its intersection with another timeframe" do
- #TODO: make these separate "it" blocks, per best practices
- (Timeframe.new(:month => 4) & Timeframe.new(:month => 6)).should be_nil
- (Timeframe.new(:month => 4) & Timeframe.new(:month => 5)).should be_nil
- (Timeframe.new(:month => 4) & Timeframe.new(:month => 4)).should == Timeframe.new(:month => 4)
- (Timeframe.new(:year => Time.now.year) & Timeframe.new(:month => 4)).should == Timeframe.new(:month => 4)
- (Timeframe.new(Date.new(2009, 2, 1), Date.new(2009, 6, 1)) & Timeframe.new(Date.new(2009, 4, 1), Date.new(2009, 8, 1))).should == Timeframe.new(Date.new(2009, 4, 1), Date.new(2009, 6, 1))
- end
- end
-
- describe '#/' do
- it "should return a fraction of another timeframe" do
- (Timeframe.new(:month => 4, :year => 2009) / Timeframe.new(:year => 2009)).should == (30.0 / 365.0)
- end
- end
-
- describe '#gaps_left_by' do
- it "should be able to ascertain gaps left by a list of other Timeframes" do
- Timeframe.new(:year => 2009).gaps_left_by(
- Timeframe.new(:year => 2009, :month => 3),
- Timeframe.new(:year => 2009, :month => 5),
- Timeframe.new(Date.new(2009, 8, 1), Date.new(2009, 11, 1)),
- Timeframe.new(Date.new(2009, 9, 1), Date.new(2009, 10, 1))
- ).should ==
- [ Timeframe.new(Date.new(2009, 1, 1), Date.new(2009, 3, 1)),
- Timeframe.new(Date.new(2009, 4, 1), Date.new(2009, 5, 1)),
- Timeframe.new(Date.new(2009, 6, 1), Date.new(2009, 8, 1)),
- Timeframe.new(Date.new(2009, 11, 1), Date.new(2010, 1, 1)) ]
- end
- end
-
- describe '#covered_by?' do
- it "should be able to ascertain gaps left by a list of other Timeframes" do
- Timeframe.new(:year => 2009).covered_by?(
- Timeframe.new(:month => 1, :year => 2009),
- Timeframe.new(Date.new(2009, 2, 1), Date.new(2010, 1, 1))
- ).should be_true
- end
- end
-
- describe '#last_year' do
- it "should return its predecessor in a previous year" do
- Timeframe.this_year.last_year.should ==
- Timeframe.new(Date.new(Date.today.year - 1, 1, 1), Date.new(Date.today.year, 1, 1))
- end
- end
-
- describe 'Timeframe:class#interval' do
- it 'should parse ISO 8601 interval format' do
- Timeframe.interval('2009-01-01/2010-01-01').should == Timeframe.new(:year => 2009)
- end
- end
-end
+require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
+require 'date'
+
+describe Timeframe do
+ describe 'initialization' do
+ it 'should create a timeframe using date strings' do
+ tf = Timeframe.new('2008-02-14', '2008-05-10')
+ tf.from.should == Date.parse('2008-02-14')
+ tf.to.should == Date.parse('2008-05-10')
+ end
+ it 'should create a timeframe using date objects' do
+ start = Date.parse('2008-02-14')
+ finish = Date.parse('2008-05-10')
+ tf = Timeframe.new(start, finish)
+ tf.from.should == start
+ tf.to.should == finish
+ end
+ it "should accept months" do
+ timeframe = Timeframe.new(:month => 1)
+ timeframe.from.should == Date.today.change(:month => 1, :day => 1)
+ timeframe.to.should == Date.today.change(:month => 2, :day => 1)
+ end
+ it "should accept month names" do
+ timeframe = Timeframe.new(:month => 'february')
+ timeframe.from.should == Date.today.change(:month => 2, :day => 1)
+ timeframe.to.should == Date.today.change(:month => 3, :day => 1)
+ end
+ it "should accept years" do
+ timeframe = Timeframe.new(:year => 2004)
+ timeframe.from.should == Date.new(2004, 1, 1)
+ timeframe.to.should == Date.new(2005, 1, 1)
+ end
+ it "should accept years and months" do
+ timeframe = Timeframe.new(:year => 2005, :month => 5)
+ timeframe.from.should == Date.new(2005, 5, 1)
+ timeframe.to.should == Date.new(2005, 6, 1)
+ end
+ it "should not accept just one date argument" do
+ lambda {
+ Timeframe.new Date.new(2007, 2, 1)
+ }.should raise_error(ArgumentError, /supply/)
+ end
+ it "should not accept end date that is earlier than start date" do
+ lambda {
+ timeframe = Timeframe.new Date.new(2008, 1, 1), Date.new(2007, 1, 1)
+ }.should raise_error(ArgumentError, /earlier/)
+ end
+ it "should not accept timeframes that cross year boundaries" do
+ lambda {
+ timeframe = Timeframe.new Date.new(2007, 1, 1), Date.new(2008, 1, 2)
+ }.should raise_error(ArgumentError, /cross/)
+ end
+ it "should optionally accept timeframes that cross year boundaries" do
+ lambda {
+ timeframe = Timeframe.new Date.new(2007, 1, 1), Date.new(2008, 1, 2), :skip_year_boundary_crossing_check => true
+ }.should_not raise_error
+ end
+ end
+
+ describe '#inspect' do
+ it 'should return the time frame in readable text' do
+ start = Date.parse('2008-02-14')
+ finish = Date.parse('2008-05-10')
+ tf = Timeframe.new(start, finish)
+ tf.inspect.should =~ /<Timeframe\(-?\d+\) 86 days starting 2008-02-14 ending 2008-05-10>/
+ end
+ end
+
+ describe '.constrained_new' do
+ let(:start) { Date.parse('2008-02-14') }
+ let(:finish) { Date.parse('2008-05-10') }
+ let(:constraint_start) { Date.parse('2008-01-01') }
+ let(:constraint_finish) { Date.parse('2008-12-01') }
+ let(:constraint) { Timeframe.new(constraint_start, constraint_finish) }
+
+ it "should allow for constrained creation" do
+ constraint = Timeframe.new :year => 2008
+ may = Timeframe.new Date.new(2008,5,1), Date.new(2008,6,1)
+ january = Timeframe.new Date.new(2008,1,1), Date.new(2008,2,1)
+ Timeframe.constrained_new(may.from, may.to, constraint).should == may
+ Timeframe.constrained_new(Date.new(2007,1,1), Date.new(2010,1,1), constraint).should == constraint
+ Timeframe.constrained_new(Date.new(2007,11,1), Date.new(2008,2,1), constraint).should == january
+ end
+ it 'should return a timeframe spanning start and end date if within constraint' do
+ tf = Timeframe.constrained_new(start, finish, constraint)
+ tf.from.should == start
+ tf.to.should == finish
+ end
+ it 'should return a timeframe spanning constraint start and end date if outside constraint' do
+ constraint = Timeframe.new(start, finish)
+ tf = Timeframe.constrained_new(constraint_start, constraint_finish, constraint)
+ tf.from.should == start
+ tf.to.should == finish
+ end
+ it 'should return a timeframe starting at constraint start' do
+ start = Date.parse('2008-01-01')
+ constraint_start = Date.parse('2008-01-14')
+ constraint = Timeframe.new(constraint_start, constraint_finish)
+ tf = Timeframe.constrained_new(start, finish, constraint)
+ tf.from.should == constraint_start
+ tf.to.should == finish
+ end
+ it 'should return a timeframe ending at constraint end' do
+ constraint_finish = Date.parse('2008-04-14')
+ constraint = Timeframe.new(constraint_start, constraint_finish)
+ tf = Timeframe.constrained_new(start, finish, constraint)
+ tf.from.should == start
+ tf.to.should == constraint_finish
+ end
+ it "should return a 0-length timeframe when constraining a timeframe by a disjoint timeframe" do
+ constraint = Timeframe.new :year => 2010
+ timeframe = Timeframe.constrained_new(
+ Date.new(2009,1,1), Date.new(2010,1,1), constraint)
+ timeframe.days.should == 0
+ end
+ end
+
+ describe '.this_year' do
+ it "should return the current year" do
+ Timeframe.this_year.should == Timeframe.new(:year => Time.now.year)
+ end
+ end
+
+ describe '#days' do
+ it "should return them number of days included" do
+ #TODO: make these separate "it" blocks, per best practices
+ Timeframe.new(Date.new(2007, 1, 1), Date.new(2008, 1, 1)).days.should == 365
+ Timeframe.new(Date.new(2008, 1, 1), Date.new(2009, 1, 1)).days.should == 366 #leap year
+ Timeframe.new(Date.new(2007, 11, 1), Date.new(2007, 12, 1)).days.should == 30
+ Timeframe.new(Date.new(2007, 11, 1), Date.new(2008, 1, 1)).days.should == 61
+ Timeframe.new(Date.new(2007, 2, 1), Date.new(2007, 3, 1)).days.should == 28
+ Timeframe.new(Date.new(2008, 2, 1), Date.new(2008, 3, 1)).days.should == 29
+ Timeframe.new(Date.new(2008, 2, 1), Date.new(2008, 2, 1)).days.should == 0
+ end
+ end
+
+ describe '#include?' do
+ it "should know if a certain date is included in the Timeframe" do
+ #TODO: make these separate "it" blocks, per best practices
+ timeframe = Timeframe.new :year => 2008, :month => 2
+ [
+ Date.new(2008, 2, 1),
+ Date.new(2008, 2, 5),
+ Date.new(2008, 2, 29)
+ ].each do |date|
+ timeframe.include?(date).should == true
+ end
+ [
+ Date.new(2008, 1, 1),
+ Date.new(2007, 2, 1),
+ Date.new(2008, 3, 1)
+ ].each do |date|
+ timeframe.include?(date).should == false
+ end
+ end
+ end
+
+ describe '#==' do
+ it "should be able to know if it's equal to another Timeframe object" do
+ Timeframe.new(:year => 2007).should == Timeframe.new(:year => 2007)
+ Timeframe.new(:year => 2004, :month => 1).should == Timeframe.new(:year => 2004, :month => 1)
+ end
+
+ it "should hash equal hash values when the timeframe is equal" do
+ Timeframe.new(:year => 2007).hash.should == Timeframe.new(:year => 2007).hash
+ Timeframe.new(:year => 2004, :month => 1).hash.should == Timeframe.new(:year => 2004, :month => 1).hash
+ end
+ end
+
+ describe '#months' do
+ it "should return an array of month-long subtimeframes" do
+ Timeframe.new(:year => 2009).months.length.should == 12
+ end
+ it "should not return an array of month-long subtimeframes if provided an inappropriate range" do
+ lambda {
+ Timeframe.new(Date.new(2009, 3, 2), Date.new(2009, 3, 5)).months
+ }.should raise_error(ArgumentError, /whole/)
+ lambda {
+ Timeframe.new(Date.new(2009, 1, 1), Date.new(2012, 1, 1), :skip_year_boundary_crossing_check => true).months
+ }.should raise_error(ArgumentError, /dangerous during/)
+ end
+ end
+
+ describe '#year' do
+ it "should return the relevant year of a timeframe" do
+ Timeframe.new(Date.new(2009, 2, 1), Date.new(2009, 4, 1)).year.should == Timeframe.new(:year => 2009)
+ end
+ it "should not return the relevant year of a timeframe if provided an inappropriate range" do
+ lambda {
+ Timeframe.new(Date.new(2009, 1, 1), Date.new(2012, 1, 1), :skip_year_boundary_crossing_check => true).year
+ }.should raise_error(ArgumentError, /dangerous during/)
+ end
+ end
+
+ describe '#&' do
+ it "should return its intersection with another timeframe" do
+ #TODO: make these separate "it" blocks, per best practices
+ (Timeframe.new(:month => 4) & Timeframe.new(:month => 6)).should be_nil
+ (Timeframe.new(:month => 4) & Timeframe.new(:month => 5)).should be_nil
+ (Timeframe.new(:month => 4) & Timeframe.new(:month => 4)).should == Timeframe.new(:month => 4)
+ (Timeframe.new(:year => Time.now.year) & Timeframe.new(:month => 4)).should == Timeframe.new(:month => 4)
+ (Timeframe.new(Date.new(2009, 2, 1), Date.new(2009, 6, 1)) & Timeframe.new(Date.new(2009, 4, 1), Date.new(2009, 8, 1))).should == Timeframe.new(Date.new(2009, 4, 1), Date.new(2009, 6, 1))
+ end
+ end
+
+ describe '#/' do
+ it "should return a fraction of another timeframe" do
+ (Timeframe.new(:month => 4, :year => 2009) / Timeframe.new(:year => 2009)).should == (30.0 / 365.0)
+ end
+ end
+
+ describe '#gaps_left_by' do
+ it "should be able to ascertain gaps left by a list of other Timeframes" do
+ Timeframe.new(:year => 2009).gaps_left_by(
+ Timeframe.new(:year => 2009, :month => 3),
+ Timeframe.new(:year => 2009, :month => 5),
+ Timeframe.new(Date.new(2009, 8, 1), Date.new(2009, 11, 1)),
+ Timeframe.new(Date.new(2009, 9, 1), Date.new(2009, 10, 1))
+ ).should ==
+ [ Timeframe.new(Date.new(2009, 1, 1), Date.new(2009, 3, 1)),
+ Timeframe.new(Date.new(2009, 4, 1), Date.new(2009, 5, 1)),
+ Timeframe.new(Date.new(2009, 6, 1), Date.new(2009, 8, 1)),
+ Timeframe.new(Date.new(2009, 11, 1), Date.new(2010, 1, 1)) ]
+ end
+ end
+
+ describe '#covered_by?' do
+ it "should be able to ascertain gaps left by a list of other Timeframes" do
+ Timeframe.new(:year => 2009).covered_by?(
+ Timeframe.new(:month => 1, :year => 2009),
+ Timeframe.new(Date.new(2009, 2, 1), Date.new(2010, 1, 1))
+ ).should be_true
+ end
+ end
+
+ describe '#last_year' do
+ it "should return its predecessor in a previous year" do
+ Timeframe.this_year.last_year.should ==
+ Timeframe.new(Date.new(Date.today.year - 1, 1, 1), Date.new(Date.today.year, 1, 1))
+ end
+ end
+
+ describe 'Timeframe:class#interval' do
+ it 'should parse ISO 8601 interval format' do
+ Timeframe.interval('2009-01-01/2010-01-01').should == Timeframe.new(:year => 2009)
+ end
+ it 'should understand its own #to_param' do
+ t = Timeframe.new(:year => 2009)
+ Timeframe.interval(t.to_param).should == t
+ end
+ end
+
+ describe '#to_json' do
+ it 'should generate JSON' do
+ Timeframe.new(:year => 2009).to_json.should == "{\"from\":\"2009-01-01\",\"to\":\"2010-01-01\"}"
+ end
+ end
+
+ describe '#to_param' do
+ it 'should generate a URL-friendly parameter' do
+ Timeframe.new(:year => 2009).to_param.should == "2009-01-01/2010-01-01"
+ end
+ end
+
+ describe '#to_s' do
+ it 'should not only look at month numbers when describing multi-year timeframes' do
+ Timeframe.multiyear(Date.parse('2008-01-01'), Date.parse('2010-01-01')).to_s.should == "the period from 01 January to 31 December 2009"
+ end
+ end
+end