From 139be35e7f5bacbd7dd5535181be14200bdedcd0 Mon Sep 17 00:00:00 2001 From: rick Date: Sun, 2 May 2010 10:21:56 -0700 Subject: [PATCH] add streak model --- lib/seinfeld.rb | 2 +- lib/seinfeld/streak.rb | 52 +++++++++++++++++++++++++++++++++++ test/streak_test.rb | 61 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 lib/seinfeld/streak.rb create mode 100644 test/streak_test.rb diff --git a/lib/seinfeld.rb b/lib/seinfeld.rb index 4a3853b..cf3098d 100644 --- a/lib/seinfeld.rb +++ b/lib/seinfeld.rb @@ -28,7 +28,7 @@ class << self attr_reader :logger end - [:Feed].each do |const| + [:Feed, :Streak].each do |const| autoload const, "seinfeld/#{const.to_s.underscore}" end diff --git a/lib/seinfeld/streak.rb b/lib/seinfeld/streak.rb new file mode 100644 index 0000000..5ca6a09 --- /dev/null +++ b/lib/seinfeld/streak.rb @@ -0,0 +1,52 @@ +class Seinfeld + # Represents a consecutive sequence of days that a user has committed. + class Streak + attr_accessor :started, :ended + + # start - First Date in the sequence that a commit was made. + # ended - Last Date (or the current Date) in the sequence that a commit + # was made. + def initialize(started = nil, ended = nil) + @started = started + @ended = ended || started + end + + # Public: Counts the number of days in the sequence, including the start + # and end. + def days + if @started && @ended + 1 + (@ended - @started).to_i.abs + else + 0 + end + end + + # Public: Checks if the streak is current. Allow streaks from yesterday + # to count, Seinfeld is confident the user will commit in time to keep + # the streak. + # + # date - The Date that we are checking against. (default: Date.today) + # + # Returns true if the Streak is current, and false if it isn't. + def current?(date = Date.today) + @ended && (@ended + 1) >= date + end + + # Public: Checks if the given date is included in the sequence. + # + # date - The Date that we are checking. + # + # Returns true if the date is in the Streak, and false if it isn't. + def include?(date) + if @started && @ended + @started <= date && @ended >= date + else + false + end + end + + def inspect + %(#{@started ? ("#{@started.year}-#{@started.month}-#{@started.day}") : :nil}..#{@ended ? ("#{@ended.year}-#{@ended.month}-#{@ended.day}") : :nil}:Streak) + end + end +end \ No newline at end of file diff --git a/test/streak_test.rb b/test/streak_test.rb new file mode 100644 index 0000000..023facd --- /dev/null +++ b/test/streak_test.rb @@ -0,0 +1,61 @@ +require File.join(File.dirname(__FILE__), "test_helper") + +class StreakTest < ActiveSupport::TestCase + setup_once do + @today = Date.today + @new_streak = Seinfeld::Streak.new + @same_streak = Seinfeld::Streak.new(Date.civil(2008, 1, 5)) + @set_streak = Seinfeld::Streak.new(Date.civil(2007, 12, 31), Date.civil(2008, 1, 5)) + @today_streak = Seinfeld::Streak.new(@today - 4, @today) + @yester_streak = Seinfeld::Streak.new(@today - 5, @today-1) + @old_streak = Seinfeld::Streak.new(@today - 6, @today-2) + end + + test "has 0 days with neither bounds set" do + assert_equal 0, @new_streak.days + end + + test "does not include outside date with neither bounds set" do + assert !@new_streak.include?(@today) + end + + test "is not current with neither bounds set" do + assert !@new_streak.current? + end + + test "has 1 day with @started and @ended set on the same day" do + assert_equal 1, @same_streak.days + end + + test "does not include outside date with @started and @ended set on the same day" do + assert !@same_streak.include?(@today) + end + + test "is not current with @started and @ended set on the same day" do + assert !@same_streak.current? + end + + test "has 5 days with @started and @ended set, ending today" do + assert_equal 5, @today_streak.days + end + + test "is current with @started and @ended set, ending today" do + assert @today_streak.current? + end + + test "has 5 days with @started and @ended set, ending yestertoday" do + assert_equal 5, @yester_streak.days + end + + test "is current with @started and @ended set, ending yestertoday" do + assert @yester_streak.current? + end + + test "has 5 days with @started and @ended set, ending 2 days ago" do + assert_equal 5, @old_streak.days + end + + test "is not current with @started and @ended set, ending 2 days ago" do + assert !@old_streak.current? + end +end \ No newline at end of file