waitfor

DESCRIPTION:

Blocks execution until a specified statement becomes true, or a specified time interval is reached, at which point an error is raised.

Useful for strengthening tests involving asynchronous or non-blocking operations.

FEATURES/PROBLEMS:

  • Accepts time intervals in two formats

    • Simple time DSL of seconds or minutes

      • 30.seconds

      • 5.minutes

    • Hash with symbols :seconds or :minutes

      • :seconds => 30

      • :minutes => 5

    • Singular forms ( 1.second or :minute => 1 ) accepted as well

  • Allows for custom exceptions, custom error messages or both

    • For custom exceptions, add ‘:exception => YourException’ to the options

      • Use either :exception or :error for custom exceptions ( both are identical in functionality )

    • For custom messages, add ‘:message => “Your Custom Message”’ to the options

  • Resolution of delay between Ruby block executions is currently 1 second, not yet configurable

  • Must use hash if specifying custom exceptions or messages, can’t mix and match simple time DSL with hash ( yet )

SYNOPSIS:

This gem is used in cases where the execution of an operation occurs asynchronously but a method to determine the operation’s status exists. In these cases you want to ‘wait for’ that operation to either complete by continuously checking the status or fail at a specified timeout.

The example below runs a non-blocking operation which can not return whether it succeeded or failed. WaitFor blocks execution, in this case, for up to 30 seconds while it continuously runs a Ruby block supplied by the user. The Ruby block in this example determines whether the previous non-blocking operation has run to completion. As the Ruby block returns false, the timer continues to count down. If it returns true, then it breaks out of the loop and continues on its way. However, if the time elapsed becomes greater than the time permitted, 30 seconds in this example, then an exception is raised.

object.some_nonblocking_operation

WaitFor.upto 30.seconds do
  object.completed?
end

Custom exception and message are specified in the examples below.

WaitFor.upto( :minute => 1, :exception => EventFailedToOccurError ) do
  event.happened?
end

WaitFor.upto( :minute => 1, :message => "Event took longer than 1 minute to complete" ) do
  event.happened?
end

WaitFor.upto( :minute => 1, :exception => EventFailedToOccurError, :message => "Event took longer than 1 minute to complete" ) do
  event.happened?
end

Finally, a few more “real world” examples.

button.click

WaitFor.upto( :minute => 1, :message => "New screen did not appear within 1 minute after clicking button" ) do
  Check.whether( new_screen ).is :visible
end

website_cluster.propagate_new_entry "Good news everyone!"

WaitFor.upto( :seconds => 30, :exception => WebsiteFailedToUpdateError ) do
  website_cluster.each_node_reports "Good news everyone!"
end

REQUIREMENTS:

  • Ruby >= 1.8.6

INSTALL:

sudo gem install waitfor --source http://gemcutter.org

LICENSE:

(The MIT License)

Copyright © 2010 James Bobowski

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.