Skip to content

Commit

Permalink
Merge pull request #12824 from sikachu/ps-testing-time-helper
Browse files Browse the repository at this point in the history
Add `#travel` and `#travel_to` to `ActiveSupport::TestCase`
  • Loading branch information
fxn committed Nov 20, 2013
2 parents 1ffa4ab + 225cd91 commit b43b6d5
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 2 deletions.
39 changes: 39 additions & 0 deletions activesupport/CHANGELOG.md
@@ -1,3 +1,42 @@
* Add `ActiveSupport::Testing::TimeHelpers#travel` and `#travel_to`. These methods change current
time to the given time or time difference by stubbing `Time.now` and `Date.today` to return the
time or date after the difference calculation, or the time or date that got passed into the
method respectively. These methods also accept a block, which will return current time back to
its original state at the end of the block.

Example for `#travel`:

Time.now # => 2013-11-09 15:34:49 -05:00
travel 1.day
Time.now # => 2013-11-10 15:34:49 -05:00
Date.today # => Sun, 10 Nov 2013

Example for `#travel_to`:

Time.now # => 2013-11-09 15:34:49 -05:00
travel_to Time.new(2004, 11, 24, 01, 04, 44)
Time.now # => 2004-11-24 01:04:44 -05:00
Date.today # => Wed, 24 Nov 2004

Both of these methods also accept a block, which will return the current time back to its
original state at the end of the block:

Time.now # => 2013-11-09 15:34:49 -05:00

travel 1.day do
User.create.created_at # => Sun, 10 Nov 2013 15:34:49 EST -05:00
end

travel_to Time.new(2004, 11, 24, 01, 04, 44) do
User.create.created_at # => Wed, 24 Nov 2004 01:04:44 EST -05:00
end

Time.now # => 2013-11-09 15:34:49 -05:00

This module is included in `ActiveSupport::TestCase` automatically.

*Prem Sichanugrist*, *DHH*

* Unify `cattr_*` interface: allow to pass a block to `cattr_reader`.

Example:
Expand Down
2 changes: 2 additions & 0 deletions activesupport/lib/active_support/test_case.rb
Expand Up @@ -7,6 +7,7 @@
require 'active_support/testing/declarative'
require 'active_support/testing/isolation'
require 'active_support/testing/constant_lookup'
require 'active_support/testing/time_helpers'
require 'active_support/core_ext/kernel/reporting'
require 'active_support/deprecation'

Expand Down Expand Up @@ -34,6 +35,7 @@ def self.for_tag(tag)
include ActiveSupport::Testing::SetupAndTeardown
include ActiveSupport::Testing::Assertions
include ActiveSupport::Testing::Deprecation
include ActiveSupport::Testing::TimeHelpers
extend ActiveSupport::Testing::Declarative

# test/unit backwards compatibility methods
Expand Down
55 changes: 55 additions & 0 deletions activesupport/lib/active_support/testing/time_helpers.rb
@@ -0,0 +1,55 @@
module ActiveSupport
module Testing
# Containing helpers that helps you test passage of time.
module TimeHelpers
# Change current time to the time in the future or in the past by a given time difference by
# stubbing +Time.now+ and +Date.today+. This method also accepts a block, which will return
# current time back to its original state at the end of the block.
#
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
# travel 1.day
# Time.current # => Sun, 10 Nov 2013 15:34:49 EST -05:00
# Date.current # => Sun, 10 Nov 2013
#
# This method also accepts a block, which will return the current time back to its original
# state at the end of the block:
#
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
# travel 1.day do
# User.create.created_at # => Sun, 10 Nov 2013 15:34:49 EST -05:00
# end
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
def travel(duration, &block)
travel_to Time.now + duration, &block
end

# Change current time to the given time by stubbing +Time.now+ and +Date.today+ to return the
# time or date passed into this method. This method also accepts a block, which will return
# current time back to its original state at the end of the block.
#
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
# travel_to Time.new(2004, 11, 24, 01, 04, 44)
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
# Date.current # => Wed, 24 Nov 2004
#
# This method also accepts a block, which will return the current time back to its original
# state at the end of the block:
#
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
# travel_to Time.new(2004, 11, 24, 01, 04, 44) do
# User.create.created_at # => Wed, 24 Nov 2004 01:04:44 EST -05:00
# end
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
def travel_to(date_or_time, &block)
Time.stubs now: date_or_time.to_time
Date.stubs today: date_or_time.to_date

if block_given?
block.call
Time.unstub :now
Date.unstub :today
end
end
end
end
end
50 changes: 48 additions & 2 deletions activesupport/test/test_test.rb
@@ -1,4 +1,6 @@
require 'abstract_unit'
require 'active_support/core_ext/date'
require 'active_support/core_ext/numeric/time'

class AssertDifferenceTest < ActiveSupport::TestCase
def setup
Expand Down Expand Up @@ -122,7 +124,6 @@ def sentinel
end
end


class SubclassSetupAndTeardownTest < SetupAndTeardownTest
setup :bar
teardown :bar
Expand All @@ -143,7 +144,6 @@ def sentinel
end
end


class TestCaseTaggedLoggingTest < ActiveSupport::TestCase
def before_setup
require 'stringio'
Expand All @@ -156,3 +156,49 @@ def test_logs_tagged_with_current_test_case
assert_match "#{self.class}: #{name}\n", @out.string
end
end

class TimeHelperTest < ActiveSupport::TestCase
setup do
Time.stubs now: Time.now
end

def test_time_helper_travel
expected_time = Time.now + 1.day
travel 1.day

assert_equal expected_time, Time.now
assert_equal expected_time.to_date, Date.today
end

def test_time_helper_travel_with_block
expected_time = Time.now + 1.day

travel 1.day do
assert_equal expected_time, Time.now
assert_equal expected_time.to_date, Date.today
end

assert_not_equal expected_time, Time.now
assert_not_equal expected_time.to_date, Date.today
end

def test_time_helper_travel_to
expected_time = Time.new(2004, 11, 24, 01, 04, 44)
travel_to expected_time

assert_equal expected_time, Time.now
assert_equal Date.new(2004, 11, 24), Date.today
end

def test_time_helper_travel_to_with_block
expected_time = Time.new(2004, 11, 24, 01, 04, 44)

travel_to expected_time do
assert_equal expected_time, Time.now
assert_equal Date.new(2004, 11, 24), Date.today
end

assert_not_equal expected_time, Time.now
assert_not_equal Date.new(2004, 11, 24), Date.today
end
end

0 comments on commit b43b6d5

Please sign in to comment.