Created
September 20, 2011 11:52
-
-
Save mattwynne/1228927 to your computer and use it in GitHub Desktop.
eventually helper method for making assertions against asynchronous systems
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# usage: | |
# it "should return a result of 5" do | |
# eventually { long_running_thing.result.should eq(5) } | |
# end | |
module AsyncHelper | |
def eventually(:options = {}) | |
timeout = options[:timeout] || 2 | |
interval = options[:interval] || 0.1 | |
time_limit = Time.now + timeout | |
loop do | |
begin | |
yield | |
rescue => error | |
end | |
return if error.nil? | |
raise error if Time.now >= time_limit | |
sleep interval | |
end | |
end | |
end | |
# Can we put this into RSpec somewhere? |
Good point. Needs to take a nap in the loop. Updated.
@mattwynne Looks like there is a syntax error on line 6 with the colon.
Stumbled across this, and realised that the gist no more works since rspec expectation failure now subclasses from Exception rather than StandardError (rspec/rspec-expectations@eafa55d#diff-f14d34de26325e61579baa36128c97cb)
Here's a fork that rescues both StandardError and RSpec::Expectations::ExpectationNotMetError:
https://gist.github.com/xam7247/290868f3c6f0f72e9b01
with returning the result so that user = eventually { User.last! }
works for instance
module Helpers::Eventually
def eventually(timeout: 2, &block)
maximum_at = Time.zone.now + timeout
loop do
begin
result = block.call
rescue => error
raise error if Time.zone.now >= maximum_at
else
return result
end
end
end
end
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Wouldn't this peg the CPU and possibly starve the thing you're waiting for?