Permalink
Browse files

Use dup of Time so reporting isn't clobbered by examples that modify …

…Time

without properly restoring it.
  • Loading branch information...
1 parent 8b461d3 commit 51a31c9ca475007b7032524ca95a74696da3d082 @dchelimsky dchelimsky committed Oct 5, 2012
View
2 Changelog.md
@@ -20,6 +20,8 @@ Enhancements
* Add `format_docstrings { |str| }` config option. It can be used to
apply formatting rules to example group and example docstrings.
(Alex Tan)
+* Use dup of Time so reporting isn't clobbered by examples that modify Time
+ without properly restoring it.
Bug fixes
View
5 lib/rspec/core.rb
@@ -105,6 +105,11 @@ def self.windows_os?
end
module Core
+ # @private
+ # This avoids issues with reporting time caused by examples that
+ # change the value/meaning of Time.now without properly restoring
+ # it.
+ Time = ::Time.dup
end
def self.const_missing(name)
View
4 lib/rspec/core/example.rb
@@ -261,7 +261,7 @@ def with_around_each_hooks(&block)
def start(reporter)
reporter.example_started(self)
- record :started_at => Time.now
+ record :started_at => RSpec::Core::Time.now
end
# @private
@@ -291,7 +291,7 @@ def finish(reporter)
end
def record_finished(status, results={})
- finished_at = Time.now
+ finished_at = RSpec::Core::Time.now
record results.merge(:status => status, :finished_at => finished_at, :run_time => (finished_at - execution_result[:started_at]))
end
View
4 lib/rspec/core/reporter.rb
@@ -38,7 +38,7 @@ def report(expected_example_count, seed=nil)
end
def start(expected_example_count)
- @start = Time.now
+ @start = RSpec::Core::Time.now
notify :start, expected_example_count
end
@@ -89,7 +89,7 @@ def finish(seed)
alias_method :abort, :finish
def stop
- @duration = Time.now - @start if @start
+ @duration = RSpec::Core::Time.now - @start if @start
notify :stop
end
View
25 spec/rspec/core/example_spec.rb
@@ -242,12 +242,12 @@ def assert(val)
group.run
results.should eq([
- "around (before)",
- "before",
- "example",
- "after",
- "around (after)"
- ])
+ "around (before)",
+ "before",
+ "example",
+ "after",
+ "around (after)"
+ ])
end
context "clearing ivars" do
@@ -349,7 +349,7 @@ def run_and_capture_reported_message(group)
blah.should be(:success)
end
end
-
+
context "in before(:each)" do
it "sets each example to pending" do
group = RSpec::Core::ExampleGroup.describe do
@@ -386,6 +386,17 @@ def run_and_capture_reported_message(group)
group.examples.first.should be_pending
end
end
+ end
+ describe "timing" do
+ it "uses RSpec::Core::Time as to not be affected by changes to time in examples" do
+ reporter = double(:reporter).as_null_object
+ group = RSpec::Core::ExampleGroup.describe
+ example = group.example
+ example.__send__ :start, reporter
+ Time.stub(:now => Time.new(2012, 10, 1))
+ example.__send__ :finish, reporter
+ expect(example.metadata[:execution_result][:run_time]).to be < 0.001
+ end
end
end
View
14 spec/rspec/core/reporter_spec.rb
@@ -99,5 +99,19 @@ module RSpec::Core
yielded.should eq(reporter)
end
end
+
+ describe "timing" do
+ it "uses RSpec::Core::Time as to not be affected by changes to time in examples" do
+ formatter = double(:formatter).as_null_object
+ reporter = Reporter.new formatter
+ reporter.start 1
+ Time.stub(:now => Time.new(2012, 10, 1))
+ duration = nil
+ formatter.stub(:dump_summary) do |duration, _, _, _|
+ duration.should be < 0.001
+ end
+ reporter.finish 1234
+ end
+ end
end
end

2 comments on commit 51a31c9

@myronmarston
RSpec member

👍

That's pretty awesome.

@dchelimsky
RSpec member

Thx :) It's been on my unofficial list for a long time and this tweet reminded me about it!

Please sign in to comment.