Merge branch 'timezones' of git://github.com/epall/tracks into master.

Re-wrote all Date-related code to use Datetimes, created a migration to get rid of all date columns in the database, and got rid of Time.now calls that were not time zone-aware. Lots of time zone goodness!
This commit is contained in:
Eric Allen 2008-09-21 18:22:48 -07:00
commit ba9a9370cc
21 changed files with 111 additions and 78 deletions

View file

@ -175,7 +175,7 @@ class ApplicationController < ActionController::Base
if show_from_date.nil?
todo.show_from=nil
else
todo.show_from = show_from_date.to_time < Time.now.utc ? nil : show_from_date
todo.show_from = show_from_date < Time.zone.now ? nil : show_from_date
end
saved = todo.save

View file

@ -22,7 +22,7 @@ class Preference < ActiveRecord::Base
def parse_date(s)
return nil if s.blank?
Date.strptime(s, date_format)
user.at_midnight(Date.strptime(s, date_format))
end
end

View file

@ -16,7 +16,7 @@ class Project < ActiveRecord::Base
state :active
state :hidden, :enter => :hide_todos, :exit => :unhide_todos
state :completed, :enter => Proc.new { |p| p.completed_at = Time.now.utc }, :exit => Proc.new { |p| p.completed_at = nil }
state :completed, :enter => Proc.new { |p| p.completed_at = Time.zone.now }, :exit => Proc.new { |p| p.completed_at = nil }
event :activate do
transitions :to => :active, :from => [:hidden, :completed]

View file

@ -12,7 +12,7 @@ class RecurringTodo < ActiveRecord::Base
t[:show_from], t.completed_at = nil, nil
t.occurences_count = 0
}
state :completed, :enter => Proc.new { |t| t.completed_at = Time.now.utc }, :exit => Proc.new { |t| t.completed_at = nil }
state :completed, :enter => Proc.new { |t| t.completed_at = Time.zone.now }, :exit => Proc.new { |t| t.completed_at = nil }
validates_presence_of :description
validates_length_of :description, :maximum => 100
@ -243,7 +243,7 @@ class RecurringTodo < ActiveRecord::Base
if self.recurrence_selector == 0
return self.every_other2
else
return Time.now.month
return Time.zone.now.month
end
end
@ -257,7 +257,7 @@ class RecurringTodo < ActiveRecord::Base
if self.recurrence_selector == 1
return self.every_other2
else
return Time.now.month
return Time.zone.now.month
end
end
@ -397,7 +397,7 @@ class RecurringTodo < ActiveRecord::Base
# determine start
if previous.nil?
start = self.start_from.nil? ? Time.now.utc : self.start_from
start = self.start_from.nil? ? Time.zone.now : self.start_from
else
# use the next day
start = previous + 1.day
@ -429,7 +429,7 @@ class RecurringTodo < ActiveRecord::Base
def get_weekly_date(previous)
# determine start
if previous == nil
start = self.start_from.nil? ? Time.now.utc : self.start_from
start = self.start_from.nil? ? Time.zone.now : self.start_from
else
start = previous + 1.day
if start.wday() == 0
@ -474,7 +474,7 @@ class RecurringTodo < ActiveRecord::Base
start += n.months
# go back to day
end
return Time.utc(start.year, start.month, day)
return Time.zone.local(start.year, start.month, day)
when 1 # relative weekday of a month
the_next = get_xth_day_of_month(self.every_other3, self.every_count, start.month, start.year)
@ -496,14 +496,14 @@ class RecurringTodo < ActiveRecord::Base
def get_xth_day_of_month(x, weekday, month, year)
if x == 5
# last -> count backwards
last_day = Time.utc(year, month, Time.days_in_month(month))
last_day = Time.zone.local(year, month, Time.days_in_month(month))
while last_day.wday != weekday
last_day -= 1.day
end
return last_day
else
# 1-4th -> count upwards
start = Time.utc(year,month,1)
start = Time.zone.local(year,month,1)
n = x
while n > 0
while start.wday() != weekday
@ -526,14 +526,14 @@ class RecurringTodo < ActiveRecord::Base
when 0 # specific day of a specific month
# if there is no next month n in this year, search in next year
if start.month >= month
start = Time.utc(start.year+1, month, 1) if start.day >= day
start = Time.utc(start.year, month, 1) if start.day <= day
start = Time.zone.local(start.year+1, month, 1) if start.day >= day
start = Time.zone.local(start.year, month, 1) if start.day <= day
end
return Time.utc(start.year, month, day)
return Time.zone.local(start.year, month, day)
when 1 # relative weekday of a specific month
# if there is no next month n in this year, search in next year
the_next = start.month > month ? Time.utc(start.year+1, month, 1) : start
the_next = start.month > month ? Time.zone.local(start.year+1, month, 1) : start
# get the xth day of the month
the_next = get_xth_day_of_month(self.every_other3, self.every_count, month, the_next.year)
@ -602,7 +602,7 @@ class RecurringTodo < ActiveRecord::Base
def determine_start(previous)
if previous.nil?
start = self.start_from.nil? ? Time.now.utc : self.start_from
start = self.start_from.nil? ? Time.zone.now : self.start_from
else
start = previous

View file

@ -13,7 +13,7 @@ class Todo < ActiveRecord::Base
# of state completed is not run, see #679
state :active, :enter => Proc.new { |t| t[:show_from], t.completed_at = nil, nil }
state :project_hidden
state :completed, :enter => Proc.new { |t| t.completed_at = Time.now.utc }, :exit => Proc.new { |t| t.completed_at = nil }
state :completed, :enter => Proc.new { |t| t.completed_at = Time.zone.now }, :exit => Proc.new { |t| t.completed_at = nil }
state :deferred
event :defer do
@ -68,6 +68,8 @@ class Todo < ActiveRecord::Base
end
def show_from=(date)
# parse Date objects into the proper timezone
date = user.at_midnight(date) if (date.is_a? Date)
activate! if deferred? && date.blank?
defer! if active? && !date.blank? && date > user.date
self[:show_from] = date

View file

@ -71,7 +71,7 @@ class User < ActiveRecord::Base
:conditions => [ 'state = ?', 'deferred' ],
:order => 'show_from ASC, todos.created_at DESC' do
def find_and_activate_ready
find(:all, :conditions => ['show_from <= ?', proxy_owner.date ]).collect { |t| t.activate! }
find(:all, :conditions => ['show_from <= ?', Time.zone.now ]).collect { |t| t.activate! }
end
end
has_many :completed_todos,
@ -169,7 +169,11 @@ class User < ActiveRecord::Base
end
def date
time.to_date
time.midnight
end
def at_midnight(date)
return TimeZone[prefs.time_zone].local(date.year, date.month, date.day, 0, 0, 0)
end
def generate_token

View file

@ -101,22 +101,22 @@
<div id="recurring_monthly" style="display:none">
<label>Settings for monthly recurring actions</label><br/>
<%= radio_button_tag('recurring_todo[monthly_selector]', 'monthly_every_x_day', true)%> Day <%=
text_field_tag('recurring_todo[monthly_every_x_day]', Time.now.mday, {"size" => 3, "tabindex" => 9}) %> on every <%=
text_field_tag('recurring_todo[monthly_every_x_day]', Time.zone.now.mday, {"size" => 3, "tabindex" => 9}) %> on every <%=
text_field_tag('recurring_todo[monthly_every_x_month]', 1, {"size" => 3, "tabindex" => 10}) %> month<br/>
<%= radio_button_tag('recurring_todo[monthly_selector]', 'monthly_every_xth_day')%> The <%=
select_tag('recurring_todo[monthly_every_xth_day]', options_for_select(@xth_day), {}) %> <%=
select_tag('recurring_todo[monthly_day_of_week]' , options_for_select(@days_of_week, Time.now.wday), {}) %> of every <%=
select_tag('recurring_todo[monthly_day_of_week]' , options_for_select(@days_of_week, Time.zone.now.wday), {}) %> of every <%=
text_field_tag('recurring_todo[monthly_every_x_month2]', 1, {"size" => 3, "tabindex" => 11}) %> month<br/>
</div>
<div id="recurring_yearly" style="display:none">
<label>Settings for yearly recurring actions</label><br/>
<%= radio_button_tag('recurring_todo[yearly_selector]', 'yearly_every_x_day', true)%> Every <%=
select_tag('recurring_todo[yearly_month_of_year]', options_for_select(@months_of_year, Time.now.month), {}) %> <%=
text_field_tag('recurring_todo[yearly_every_x_day]', Time.now.day, "size" => 3, "tabindex" => 9) %><br/>
select_tag('recurring_todo[yearly_month_of_year]', options_for_select(@months_of_year, Time.zone.now.month), {}) %> <%=
text_field_tag('recurring_todo[yearly_every_x_day]', Time.zone.now.day, "size" => 3, "tabindex" => 9) %><br/>
<%= radio_button_tag('recurring_todo[yearly_selector]', 'yearly_every_xth_day')%> The <%=
select_tag('recurring_todo[yearly_every_xth_day]', options_for_select(@xth_day), {}) %> <%=
select_tag('recurring_todo[yearly_day_of_week]', options_for_select(@days_of_week, Time.now.wday), {}) %> of <%=
select_tag('recurring_todo[yearly_month_of_year2]', options_for_select(@months_of_year, Time.now.month), {}) %><br/>
select_tag('recurring_todo[yearly_day_of_week]', options_for_select(@days_of_week, Time.zone.now.wday), {}) %> of <%=
select_tag('recurring_todo[yearly_month_of_year2]', options_for_select(@months_of_year, Time.zone.now.month), {}) %><br/>
</div>
<div id="recurring_target">
<label>Set recurrence on</label><br/>

View file

@ -0,0 +1,27 @@
class ChangeDatesToDatetimes < ActiveRecord::Migration
def self.up
change_column :todos, :show_from, :datetime
change_column :todos, :due, :datetime
change_column :recurring_todos, :start_from, :datetime
change_column :recurring_todos, :end_date, :datetime
User.all(:include => [:todos, :recurring_todos]).each do |user|
user.todos.each do |todo|
todo.update_attribute(:show_from, user.at_midnight(todo.show_from)) unless todo.show_from.nil?
todo.update_attribute(:due, user.at_midnight(todo.due)) unless todo.due.nil?
end
user.recurring_todos.each do |todo|
todo.update_attribute(:start_from, user.at_midnight(todo.start_from)) unless todo.start_from.nil?
todo.update_attribute(:end_date, user.at_midnight(todo.end_date)) unless todo.end_date.nil?
end
end
end
def self.down
change_column :todos, :show_from, :date
change_column :todos, :due, :date
change_column :recurring_todos, :start_from, :date
change_column :recurring_todos, :end_date, :date
end
end

View file

@ -10,7 +10,7 @@ describe Todo do
def create_todo(attributes={})
todo = Todo.new(valid_attributes(attributes))
todo.stub!(:user).and_return(mock_model(User, :date => Time.now))
todo.stub!(:user).and_return(mock_model(User, :date => Time.zone.now))
todo.save!
todo
end
@ -32,7 +32,7 @@ describe Todo do
it 'ensures that show_from is a date in the future' do
todo = Todo.new(valid_attributes)
todo.stub!(:user).and_return(mock_model(User, :date => Time.now))
todo.stub!(:user).and_return(mock_model(User, :date => Time.zone.now))
todo.show_from = 3.days.ago
todo.should have(1).error_on(:show_from)
end

View file

@ -185,8 +185,9 @@ describe User do
user.save!
user.create_preference
user.preference.update_attribute('time_zone', 'Pacific Time (US & Canada)')
# Time.zone = 'Pacific Time (US & Canada)'
Time.stub!(:now).and_return(Time.new.end_of_day - 20.minutes)
todo = user.todos.build(:description => 'test task', :context => context, :show_from => user.date + 1)
todo = user.todos.build(:description => 'test task', :context => context, :show_from => user.date + 1.days)
todo.save!
user.deferred_todos.find_and_activate_ready

View file

@ -25,7 +25,7 @@ class ProjectsControllerTest < TodoContainerControllerTestBase
assert_equal 1, assigns['deferred'].size
t = p.not_done_todos[0]
t.show_from = 1.days.from_now.utc.to_date
t.show_from = 1.days.from_now.utc
t.save!
get :show, :id => p.to_param

View file

@ -114,7 +114,7 @@ class RecurringTodosControllerTest < ActionController::TestCase
new_todo = Todo.find_by_recurring_todo_id 5
# due date should be the target_date
assert_equal Time.utc(target_date.year, target_date.month, target_date.day), new_todo.due
assert_equal users(:admin_user).at_midnight(Date.new(target_date.year, target_date.month, target_date.day)), new_todo.due
# show_from should be nil since now+4.days-10.days is in the past
assert_equal nil, new_todo.show_from

View file

@ -137,7 +137,7 @@ class TodosControllerTest < Test::Rails::TestCase
assert_equal "Call Warren Buffet to find out how much he makes per day", t.description
assert_equal "foo, bar", t.tag_list
expected = Date.new(2006,11,30)
actual = t.due
actual = t.due.to_date
assert_equal expected, actual, "Expected #{expected.to_s(:db)}, was #{actual.to_s(:db)}"
end
@ -328,7 +328,7 @@ class TodosControllerTest < Test::Rails::TestCase
assert t.active?
assert_equal 'test notes', t.notes
assert_nil t.show_from
assert_equal Date.new(2007,1,2).to_s, t.due.to_s
assert_equal Date.new(2007,1,2), t.due.to_date
end
def test_mobile_create_action_redirects_to_mobile_home_page_when_successful

View file

@ -71,7 +71,7 @@ class Test::Rails::TestCase < Test::Unit::TestCase
end
def next_week
1.week.from_now.utc.to_date
1.week.from_now.utc
end
# Courtesy of http://habtm.com/articles/2006/02/20/assert-yourself-man-redirecting-with-rjs

View file

@ -20,7 +20,7 @@ class PreferenceTest < Test::Rails::TestCase
end
def test_parse_date
assert_equal Date.new(2007, 5, 20).to_s, @admin_user.preference.parse_date('20/5/2007').to_s
assert_equal @admin_user.at_midnight(Date.new(2007, 5, 20)).to_s, @admin_user.preference.parse_date('20/5/2007').to_s
end
def test_parse_date_returns_nil_if_string_is_empty

View file

@ -118,7 +118,7 @@ class ProjectTest < Test::Rails::TestCase
def test_deferred_todos
assert_equal 1, @timemachine.deferred_todos.size
t = @timemachine.not_done_todos[0]
t.show_from = 1.days.from_now.utc.to_date
t.show_from = 1.days.from_now.utc
t.save!
assert_equal 2, Project.find(@timemachine.id).deferred_todos.size
end

View file

@ -15,13 +15,13 @@ class RecurringTodoTest < Test::Rails::TestCase
@in_three_days = Time.now.utc + 3.days
@in_four_days = @in_three_days + 1.day # need a day after start_from
@friday = Time.utc(2008,6,6)
@saturday = Time.utc(2008,6,7)
@sunday = Time.utc(2008,6,8) # june 8, 2008 was a sunday
@monday = Time.utc(2008,6,9)
@tuesday = Time.utc(2008,6,10)
@wednesday = Time.utc(2008,6,11)
@thursday = Time.utc(2008,6,12)
@friday = Time.zone.local(2008,6,6)
@saturday = Time.zone.local(2008,6,7)
@sunday = Time.zone.local(2008,6,8) # june 8, 2008 was a sunday
@monday = Time.zone.local(2008,6,9)
@tuesday = Time.zone.local(2008,6,10)
@wednesday = Time.zone.local(2008,6,11)
@thursday = Time.zone.local(2008,6,12)
end
def test_pattern_text
@ -134,19 +134,19 @@ class RecurringTodoTest < Test::Rails::TestCase
def test_monthly_pattern
due_date = @monthly_every_last_friday.get_due_date(@sunday)
assert_equal Time.utc(2008,6,27), due_date
assert_equal Time.zone.local(2008,6,27), due_date
friday_is_last_day_of_month = Time.utc(2008,10,31)
friday_is_last_day_of_month = Time.zone.local(2008,10,31)
due_date = @monthly_every_last_friday.get_due_date(friday_is_last_day_of_month-1.day )
assert_equal friday_is_last_day_of_month , due_date
@monthly_every_third_friday = @monthly_every_last_friday
@monthly_every_third_friday.every_other3=3 #third
due_date = @monthly_every_last_friday.get_due_date(@sunday) # june 8th 2008
assert_equal Time.utc(2008, 6, 20), due_date
assert_equal Time.zone.local(2008, 6, 20), due_date
# set date past third friday of this month
due_date = @monthly_every_last_friday.get_due_date(Time.utc(2008,6,21)) # june 21th 2008
assert_equal Time.utc(2008, 8, 15), due_date # every 2 months, so aug
due_date = @monthly_every_last_friday.get_due_date(Time.zone.local(2008,6,21)) # june 21th 2008
assert_equal Time.zone.local(2008, 8, 15), due_date # every 2 months, so aug
@monthly = @monthly_every_last_friday
@monthly.recurrence_selector=0
@ -157,12 +157,12 @@ class RecurringTodoTest < Test::Rails::TestCase
assert_equal @sunday, due_date # june 8th
due_date = @monthly.get_due_date(@sunday) # june 8th
assert_equal Time.utc(2008,8,8), due_date # aug 8th
assert_equal Time.zone.local(2008,8,8), due_date # aug 8th
end
def test_yearly_pattern
# beginning of same year
due_date = @yearly.get_due_date(Time.utc(2008,2,10)) # feb 10th
due_date = @yearly.get_due_date(Time.zone.local(2008,2,10)) # feb 10th
assert_equal @sunday, due_date # june 8th
# same month, previous date
@ -173,20 +173,20 @@ class RecurringTodoTest < Test::Rails::TestCase
# same month, day after
due_date = @yearly.get_due_date(@monday) # june 9th
assert_equal Time.utc(2009,6,8), due_date # june 8th next year
assert_equal Time.zone.local(2009,6,8), due_date # june 8th next year
@yearly.recurrence_selector = 1
@yearly.every_other3 = 2 # second
@yearly.every_count = 3 # wednesday
# beginning of same year
due_date = @yearly.get_due_date(Time.utc(2008,2,10)) # feb 10th
assert_equal Time.utc(2008,6,11), due_date # june 11th
due_date = @yearly.get_due_date(Time.zone.local(2008,2,10)) # feb 10th
assert_equal Time.zone.local(2008,6,11), due_date # june 11th
# same month, before second wednesday
due_date = @yearly.get_due_date(@saturday) # june 7th
assert_equal Time.utc(2008,6,11), due_date # june 11th
assert_equal Time.zone.local(2008,6,11), due_date # june 11th
# same month, after second wednesday
due_date = @yearly.get_due_date(Time.utc(2008,6,12)) # june 7th
assert_equal Time.utc(2009,6,10), due_date # june 10th
due_date = @yearly.get_due_date(Time.zone.local(2008,6,12)) # june 7th
assert_equal Time.zone.local(2009,6,10), due_date # june 10th
# test handling of nil
due_date1 = @yearly.get_due_date(nil)
@ -207,24 +207,24 @@ class RecurringTodoTest < Test::Rails::TestCase
due_date = @every_day.get_due_date(@in_four_days)
assert_equal @in_four_days+1.day, due_date
@weekly_every_day.start_from = Time.utc(2020,1,1)
assert_equal Time.utc(2020,1,1), @weekly_every_day.get_due_date(nil)
assert_equal Time.utc(2020,1,1), @weekly_every_day.get_due_date(Time.utc(2019,10,1))
assert_equal Time.utc(2020,1,10), @weekly_every_day.get_due_date(Time.utc(2020,1,9))
@weekly_every_day.start_from = Time.zone.local(2020,1,1)
assert_equal Time.zone.local(2020,1,1), @weekly_every_day.get_due_date(nil)
assert_equal Time.zone.local(2020,1,1), @weekly_every_day.get_due_date(Time.zone.local(2019,10,1))
assert_equal Time.zone.local(2020,1,10), @weekly_every_day.get_due_date(Time.zone.local(2020,1,9))
@monthly_every_last_friday.start_from = Time.utc(2020,1,1)
assert_equal Time.utc(2020,1,31), @monthly_every_last_friday.get_due_date(nil) # last friday of jan
assert_equal Time.utc(2020,1,31), @monthly_every_last_friday.get_due_date(Time.utc(2019,12,1)) # last friday of jan
assert_equal Time.utc(2020,2,28), @monthly_every_last_friday.get_due_date(Time.utc(2020,2,1)) # last friday of feb
@monthly_every_last_friday.start_from = Time.zone.local(2020,1,1)
assert_equal Time.zone.local(2020,1,31), @monthly_every_last_friday.get_due_date(nil) # last friday of jan
assert_equal Time.zone.local(2020,1,31), @monthly_every_last_friday.get_due_date(Time.zone.local(2019,12,1)) # last friday of jan
assert_equal Time.zone.local(2020,2,28), @monthly_every_last_friday.get_due_date(Time.zone.local(2020,2,1)) # last friday of feb
# start from after june 8th 2008
@yearly.start_from = Time.utc(2020,6,12)
assert_equal Time.utc(2021,6,8), @yearly.get_due_date(nil) # jun 8th next year
assert_equal Time.utc(2021,6,8), @yearly.get_due_date(Time.utc(2019,6,1)) # also next year
assert_equal Time.utc(2021,6,8), @yearly.get_due_date(Time.utc(2020,6,15)) # also next year
@yearly.start_from = Time.zone.local(2020,6,12)
assert_equal Time.zone.local(2021,6,8), @yearly.get_due_date(nil) # jun 8th next year
assert_equal Time.zone.local(2021,6,8), @yearly.get_due_date(Time.zone.local(2019,6,1)) # also next year
assert_equal Time.zone.local(2021,6,8), @yearly.get_due_date(Time.zone.local(2020,6,15)) # also next year
this_year = Time.now.utc.year
@yearly.start_from = Time.utc(this_year+1,6,12)
@yearly.start_from = Time.zone.local(this_year+1,6,12)
due_date = @yearly.get_due_date(nil)
assert_equal due_date.year, this_year+2
end

View file

@ -18,7 +18,7 @@ class TodoCreateParamsHelperTest < Test::Rails::TestCase
end
def test_show_from_accessor
expected_date = Time.now.to_date
expected_date = Time.now
params = { 'todo' => { 'show_from' => expected_date}}
prefs = flexmock()
params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs)
@ -26,7 +26,7 @@ class TodoCreateParamsHelperTest < Test::Rails::TestCase
end
def test_due_accessor
expected_date = Time.now.to_date
expected_date = Time.now
params = { 'todo' => { 'due' => expected_date}}
prefs = flexmock()
params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs)

View file

@ -68,9 +68,8 @@ class TodoTest < Test::Rails::TestCase
def test_validate_show_from_must_be_a_date_in_the_future
t = @not_completed2
t[:show_from] = 1.week.ago.to_date # we have to set this via the indexer because show_from=() updates the state
t[:show_from] = 1.week.ago # we have to set this via the indexer because show_from=() updates the state
# and actual show_from value appropriately based on the date
assert_equal 1.week.ago.to_date, t.show_from
assert !t.save
assert_equal 1, t.errors.count
assert_equal "must be a date in the future", t.errors.on(:show_from)
@ -118,7 +117,7 @@ class TodoTest < Test::Rails::TestCase
def test_activate_also_saves
t = @not_completed1
t.show_from = 1.week.from_now.to_date
t.show_from = 1.week.from_now
t.save!
assert t.deferred?
t.reload

View file

@ -235,7 +235,7 @@ class UserTest < Test::Rails::TestCase
def test_find_and_activate_deferred_todos_that_are_ready
assert_equal 1, @admin_user.deferred_todos.count
@admin_user.deferred_todos[0].show_from = @admin_user.time.to_date
@admin_user.deferred_todos[0].show_from = Time.now.utc - 5.seconds
@admin_user.deferred_todos[0].save
@admin_user.deferred_todos.reload
@admin_user.deferred_todos.find_and_activate_ready

View file

@ -20,28 +20,28 @@ class TodosHelperTest < Test::Rails::HelperTestCase
end
def test_show_date_in_past
date = 3.days.ago.to_date
date = 3.days.ago
html = show_date(date)
formatted_date = format_date(date)
assert_equal %Q{<a title="#{formatted_date}"><span class="red">Scheduled to show 3 days ago</span></a> }, html
end
def test_show_date_today
date = Time.zone.now.to_date
date = Time.zone.now
html = show_date(date)
formatted_date = format_date(date)
assert_equal %Q{<a title="#{formatted_date}"><span class="amber">Show Today</span></a> }, html
end
def test_show_date_tomorrow
date = 1.day.from_now.to_date
date = 1.day.from_now
html = show_date(date)
formatted_date = format_date(date)
assert_equal %Q{<a title="#{formatted_date}"><span class="amber">Show Tomorrow</span></a> }, html
end
def test_show_date_future
date = 10.days.from_now.to_date
date = 10.days.from_now
html = show_date(date)
formatted_date = format_date(date)
assert_equal %Q{<a title="#{formatted_date}"><span class="green">Show in 10 days</span></a> }, html