Permalink
Browse files

Finish re-implementation of by_star

  • Loading branch information...
1 parent 7e898db commit 61a06c0e237768c835497d64cbea256875a0f010 @radar committed Feb 18, 2012
Showing with 100 additions and 0 deletions.
  1. +2 −0 lib/by_star.rb
  2. +51 −0 lib/by_star/by_fortnight.rb
  3. +47 −0 spec/by_star/by_fortnight_spec.rb
View
@@ -1,5 +1,6 @@
require 'by_star/by_year'
require 'by_star/by_month'
+require 'by_star/by_fortnight'
module ByStar
@@ -10,6 +11,7 @@ def by_star_field(field=nil)
include ByYear
include ByMonth
+ include ByFortnight
class ParseError < StandardError
@@ -0,0 +1,51 @@
+module ByStar
+ module ByFortnight
+ def by_fortnight(time=nil, options={})
+ options.symbolize_keys!
+ time ||= Time.zone.now.beginning_of_day
+ send("by_fortnight_#{time_klass(time)}", time, options)
+ end
+
+ private
+
+ def by_fortnight_Time_or_Date(time, options={})
+ # We want to get the current fortnight and so...
+ # We need to find the current week number and take one from it,
+ # so that we are correctly offset from the start of the year.
+ # The first fortnight of the year should of course start on the 1st January,
+ # and not the beginning of that week.
+ start_time = time.beginning_of_year + (time.strftime("%U").to_i - 1).weeks
+ between(start_time, start_time + 2.weeks, options)
+ end
+ alias_method :by_fortnight_Time, :by_fortnight_Time_or_Date
+ alias_method :by_fortnight_Date, :by_fortnight_Time_or_Date
+
+ def by_fortnight_String_or_Fixnum(weeks, options={})
+ weeks = weeks.to_i
+ current_time = Time.zone.local(options[:year] || Time.zone.now.year)
+ if weeks <= 26
+ start_time = current_time + (weeks * 2).weeks
+ between(start_time, start_time + 2.weeks, options)
+ else
+ raise ParseError, "by_fortnight takes only a Time, Date or a Fixnum (less than or equal to 26)."
+ end
+ end
+ alias_method :by_fortnight_String, :by_fortnight_String_or_Fixnum
+ alias_method :by_fortnight_Fixnum, :by_fortnight_String_or_Fixnum
+
+
+
+ # def omg
+ # time.beginning_of_year + (time.strftime("%U").to_i).weeks
+ # if time.is_a?(Numeric) && time <= 26
+ # Time.utc(year, 1, 1) + ((time.to_i) * 2).weeks
+ # else
+ # raise ParseError, "by_fortnight takes only a Time or Date object, a Fixnum (less than or equal to 26) or a Chronicable string."
+ # end
+
+ # between(start_time.beginning_of_week, start_time + 2.weeks)
+ # end
+
+
+ end
+end
@@ -0,0 +1,47 @@
+require 'spec_helper'
+
+describe "by fortnight" do
+
+ def find_posts(time=nil, options={})
+ Post.by_fortnight(time, options)
+ end
+
+ def posts_count(time=nil, options={})
+ find_posts(time, options).count
+ end
+
+ it "should be able to find posts in the current fortnight" do
+ posts_count.should eql(8)
+ end
+
+ it "should be able to find posts in the 1st fortnight of the current year" do
+ Post.by_fortnight(0).to_sql
+ posts_count(0).should eql(8)
+ posts_count("0").should eql(8)
+ # There was previously a situation where incorrect time zone math
+ # caused the 'post 1' post to NOT appear, so count would be 7, rather than 8.
+ # So this line simply regression tests that problem.
+ Post.by_fortnight(0).map(&:text).should include("post 1")
+ end
+
+ it "should be able to find posts for a fortnight ago" do
+ posts_count(2.weeks.ago).should eql(0)
+ end
+
+ it "should be able to find posts if given a Date object" do
+ posts_count(Date.today).should eql(8)
+ end
+
+ it "should be able to find posts for a given fortnight in a year" do
+ posts_count(0, :year => Time.zone.now.year - 1).should eql(1)
+ end
+
+ it "should raise an error when given an invalid argument" do
+ lambda { find_posts(27) }.should raise_error(ByStar::ParseError, "by_fortnight takes only a Time, Date or a Fixnum (less than or equal to 26).")
+ end
+
+ it "should be able to use an alternative field" do
+ Event.by_fortnight(nil, :field => "start_time").count.should eql(2)
+ end
+end
+

0 comments on commit 61a06c0

Please sign in to comment.