Browse files

Merge pull request #13883 from rafaelfranca/rm-time-travel

Alternative implementation to make time travel not dependent on mocha
  • Loading branch information...
2 parents 5d1f0d4 + 06e06cd commit db5d6bf74f3f6423e56120198685b8665e59616e @rafaelfranca rafaelfranca committed Jan 30, 2014
Showing with 53 additions and 4 deletions.
  1. +53 −4 activesupport/lib/active_support/testing/time_helpers.rb
View
57 activesupport/lib/active_support/testing/time_helpers.rb
@@ -1,7 +1,51 @@
module ActiveSupport
module Testing
+ class SimpleStubs # :nodoc:
+ Stub = Struct.new(:object, :method_name, :original_method)
+
+ def initialize
+ @stubs = {}
+ end
+
+ def stub_object(object, method_name, return_value)
+ key = [object.object_id, method_name]
+
+ if (stub = @stubs[key])
+ unstub_object(stub)
+ end
+
+ new_name = "__simple_stub__#{method_name}"
+
+ @stubs[key] = Stub.new(object, method_name, new_name)
+
+ object.singleton_class.send :alias_method, new_name, method_name
+ object.define_singleton_method(method_name) { return_value }
+ end
+
+ def unstub_all!
+ @stubs.each_value do |stub|
+ unstub_object(stub)
+ end
+ @stubs = {}
+ end
+
+ private
+
+ def unstub_object(stub)
+ singleton_class = stub.object.singleton_class
+ singleton_class.send :undef_method, stub.method_name
+ singleton_class.send :alias_method, stub.method_name, stub.original_method
+ singleton_class.send :undef_method, stub.original_method
+ end
+ end
+
# Containing helpers that helps you test passage of time.
module TimeHelpers
+ def after_teardown #:nodoc:
+ simple_stubs.unstub_all!
+ super
+ end
+
# 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+. Note that the stubs are automatically removed
# at the end of each test.
@@ -41,15 +85,20 @@ def travel(duration, &block)
# 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
+ simple_stubs.stub_object(Time, :now, date_or_time.to_time)
+ simple_stubs.stub_object(Date, :today, date_or_time.to_date)
if block_given?
block.call
- Time.unstub :now
- Date.unstub :today
+ simple_stubs.unstub_all!
end
end
+
+ private
+
+ def simple_stubs
+ @simple_stubs ||= SimpleStubs.new
+ end
end
end
end

0 comments on commit db5d6bf

Please sign in to comment.