ohammersmith-webrat 0.4.4.98

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/History.txt +333 -0
  2. data/MIT-LICENSE.txt +19 -0
  3. data/README.rdoc +85 -0
  4. data/Rakefile +156 -0
  5. data/install.rb +1 -0
  6. data/lib/webrat/core/configuration.rb +98 -0
  7. data/lib/webrat/core/elements/area.rb +31 -0
  8. data/lib/webrat/core/elements/element.rb +33 -0
  9. data/lib/webrat/core/elements/field.rb +403 -0
  10. data/lib/webrat/core/elements/form.rb +103 -0
  11. data/lib/webrat/core/elements/label.rb +31 -0
  12. data/lib/webrat/core/elements/link.rb +92 -0
  13. data/lib/webrat/core/elements/select_option.rb +35 -0
  14. data/lib/webrat/core/locators/area_locator.rb +38 -0
  15. data/lib/webrat/core/locators/button_locator.rb +54 -0
  16. data/lib/webrat/core/locators/field_by_id_locator.rb +37 -0
  17. data/lib/webrat/core/locators/field_labeled_locator.rb +56 -0
  18. data/lib/webrat/core/locators/field_locator.rb +25 -0
  19. data/lib/webrat/core/locators/field_named_locator.rb +41 -0
  20. data/lib/webrat/core/locators/form_locator.rb +19 -0
  21. data/lib/webrat/core/locators/label_locator.rb +34 -0
  22. data/lib/webrat/core/locators/link_locator.rb +66 -0
  23. data/lib/webrat/core/locators/locator.rb +20 -0
  24. data/lib/webrat/core/locators/select_option_locator.rb +59 -0
  25. data/lib/webrat/core/locators.rb +20 -0
  26. data/lib/webrat/core/logging.rb +21 -0
  27. data/lib/webrat/core/matchers/have_content.rb +73 -0
  28. data/lib/webrat/core/matchers/have_selector.rb +74 -0
  29. data/lib/webrat/core/matchers/have_tag.rb +21 -0
  30. data/lib/webrat/core/matchers/have_xpath.rb +147 -0
  31. data/lib/webrat/core/matchers.rb +4 -0
  32. data/lib/webrat/core/methods.rb +61 -0
  33. data/lib/webrat/core/mime.rb +29 -0
  34. data/lib/webrat/core/save_and_open_page.rb +50 -0
  35. data/lib/webrat/core/scope.rb +350 -0
  36. data/lib/webrat/core/session.rb +281 -0
  37. data/lib/webrat/core/xml/hpricot.rb +19 -0
  38. data/lib/webrat/core/xml/nokogiri.rb +76 -0
  39. data/lib/webrat/core/xml/rexml.rb +24 -0
  40. data/lib/webrat/core/xml.rb +115 -0
  41. data/lib/webrat/core.rb +14 -0
  42. data/lib/webrat/core_extensions/blank.rb +58 -0
  43. data/lib/webrat/core_extensions/deprecate.rb +8 -0
  44. data/lib/webrat/core_extensions/detect_mapped.rb +12 -0
  45. data/lib/webrat/core_extensions/meta_class.rb +6 -0
  46. data/lib/webrat/core_extensions/nil_to_param.rb +5 -0
  47. data/lib/webrat/core_extensions/tcp_socket.rb +27 -0
  48. data/lib/webrat/mechanize.rb +74 -0
  49. data/lib/webrat/merb.rb +9 -0
  50. data/lib/webrat/merb_session.rb +65 -0
  51. data/lib/webrat/rack.rb +24 -0
  52. data/lib/webrat/rails.rb +105 -0
  53. data/lib/webrat/rspec-rails.rb +13 -0
  54. data/lib/webrat/selenium/application_server.rb +71 -0
  55. data/lib/webrat/selenium/location_strategy_javascript/button.js +12 -0
  56. data/lib/webrat/selenium/location_strategy_javascript/label.js +16 -0
  57. data/lib/webrat/selenium/location_strategy_javascript/webrat.js +5 -0
  58. data/lib/webrat/selenium/location_strategy_javascript/webratlink.js +9 -0
  59. data/lib/webrat/selenium/location_strategy_javascript/webratlinkwithin.js +15 -0
  60. data/lib/webrat/selenium/location_strategy_javascript/webratselectwithoption.js +5 -0
  61. data/lib/webrat/selenium/matchers/have_content.rb +66 -0
  62. data/lib/webrat/selenium/matchers/have_selector.rb +49 -0
  63. data/lib/webrat/selenium/matchers/have_tag.rb +72 -0
  64. data/lib/webrat/selenium/matchers/have_xpath.rb +45 -0
  65. data/lib/webrat/selenium/matchers.rb +4 -0
  66. data/lib/webrat/selenium/merb_application_server.rb +48 -0
  67. data/lib/webrat/selenium/rails_application_server.rb +42 -0
  68. data/lib/webrat/selenium/selenium_extensions.js +6 -0
  69. data/lib/webrat/selenium/selenium_rc_server.rb +80 -0
  70. data/lib/webrat/selenium/selenium_session.rb +241 -0
  71. data/lib/webrat/selenium/sinatra_application_server.rb +35 -0
  72. data/lib/webrat/selenium.rb +80 -0
  73. data/lib/webrat/sinatra.rb +44 -0
  74. data/lib/webrat.rb +34 -0
  75. data/vendor/selenium-server.jar +0 -0
  76. metadata +147 -0
@@ -0,0 +1,281 @@
1
+ require "forwardable"
2
+ require "ostruct"
3
+
4
+ require "webrat/core/mime"
5
+ require "webrat/core/save_and_open_page"
6
+
7
+ module Webrat
8
+ # A page load or form submission returned an unsuccessful response code (500-599)
9
+ class PageLoadError < WebratError
10
+ end
11
+
12
+ class InfiniteRedirectError < WebratError
13
+ end
14
+
15
+ def self.session_class
16
+ case Webrat.configuration.mode
17
+ when :rails
18
+ RailsSession
19
+ when :merb
20
+ MerbSession
21
+ when :selenium
22
+ SeleniumSession
23
+ when :rack
24
+ RackSession
25
+ when :sinatra
26
+ SinatraSession
27
+ when :mechanize
28
+ MechanizeSession
29
+ else
30
+ raise WebratError.new(<<-STR)
31
+ Unknown Webrat mode: #{Webrat.configuration.mode.inspect}
32
+
33
+ Please ensure you have a Webrat configuration block that specifies a mode
34
+ in your test_helper.rb, spec_helper.rb, or env.rb (for Cucumber).
35
+
36
+ This configure block supercedes the need to require "webrat/<framework>".
37
+
38
+ For example:
39
+
40
+ Webrat.configure do |config|
41
+ config.mode = :rails
42
+ end
43
+ STR
44
+ end
45
+ end
46
+
47
+ class Session
48
+ extend Forwardable
49
+ include Logging
50
+ include SaveAndOpenPage
51
+ attr_reader :current_url
52
+ attr_reader :elements
53
+
54
+ def initialize(context = nil) #:nodoc:
55
+ @http_method = :get
56
+ @data = {}
57
+ @default_headers = {}
58
+ @custom_headers = {}
59
+ @context = context
60
+
61
+ reset
62
+ end
63
+
64
+ def current_dom #:nodoc:
65
+ current_scope.dom
66
+ end
67
+
68
+ # For backwards compatibility -- removing in 1.0
69
+ def current_page #:nodoc:
70
+ page = OpenStruct.new
71
+ page.url = @current_url
72
+ page.http_method = @http_method
73
+ page.data = @data
74
+ page
75
+ end
76
+
77
+ def doc_root #:nodoc:
78
+ nil
79
+ end
80
+
81
+ def header(key, value)
82
+ @custom_headers[key] = value
83
+ end
84
+
85
+ def http_accept(mime_type)
86
+ header('Accept', Webrat::MIME.mime_type(mime_type))
87
+ end
88
+
89
+ def basic_auth(user, pass)
90
+ encoded_login = ["#{user}:#{pass}"].pack("m*")
91
+ header('HTTP_AUTHORIZATION', "Basic #{encoded_login}")
92
+ end
93
+
94
+ def headers #:nodoc:
95
+ @default_headers.dup.merge(@custom_headers.dup)
96
+ end
97
+
98
+ def request_page(url, http_method, data) #:nodoc:
99
+ h = headers
100
+ h['HTTP_REFERER'] = @current_url if @current_url
101
+
102
+ debug_log "REQUESTING PAGE: #{http_method.to_s.upcase} #{url} with #{data.inspect} and HTTP headers #{h.inspect}"
103
+ if h.empty?
104
+ send "#{http_method}", url, data || {}
105
+ else
106
+ send "#{http_method}", url, data || {}, h
107
+ end
108
+
109
+ save_and_open_page if exception_caught? && Webrat.configuration.open_error_files?
110
+ raise PageLoadError.new("Page load was not successful (Code: #{response_code.inspect}):\n#{formatted_error}") unless success_code?
111
+
112
+ reset
113
+
114
+ @current_url = url
115
+ @http_method = http_method
116
+ @data = data
117
+
118
+ if internal_redirect?
119
+ check_for_infinite_redirects
120
+ request_page(response_location, :get, {})
121
+ end
122
+
123
+ return response
124
+ end
125
+
126
+ def check_for_infinite_redirects
127
+ if current_url == response_location
128
+ @_identical_redirect_count ||= 0
129
+ @_identical_redirect_count += 1
130
+ end
131
+
132
+ if infinite_redirect_limit_exceeded?
133
+ raise InfiniteRedirectError.new("#{Webrat.configuration.infinite_redirect_limit} redirects to the same URL (#{current_url.inspect})")
134
+ end
135
+ end
136
+
137
+ def infinite_redirect_limit_exceeded?
138
+ Webrat.configuration.infinite_redirect_limit &&
139
+ (@_identical_redirect_count || 0) > Webrat.configuration.infinite_redirect_limit
140
+ end
141
+
142
+ def success_code? #:nodoc:
143
+ (200..499).include?(response_code)
144
+ end
145
+
146
+ def redirect? #:nodoc:
147
+ response_code / 100 == 3
148
+ end
149
+
150
+ def internal_redirect?
151
+ return false unless redirect?
152
+ #should keep internal_redirects if the subdomain changes
153
+ current_host_domain = current_host.split('.')[-2..-1].join('.') rescue current_host
154
+ response_location_host_domain = response_location_host.split('.')[-2..-1].join('.') rescue response_location_host
155
+ current_host_domain == response_location_host_domain
156
+ end
157
+
158
+ #easy helper to pull out where we were redirected to
159
+ def redirected_to
160
+ redirect? ? response_location : nil
161
+ end
162
+
163
+ def exception_caught? #:nodoc:
164
+ response_body =~ /Exception caught/
165
+ end
166
+
167
+ def current_scope #:nodoc:
168
+ scopes.last || page_scope
169
+ end
170
+
171
+ # Reloads the last page requested. Note that this will resubmit forms
172
+ # and their data.
173
+ def reload
174
+ request_page(@current_url, @http_method, @data)
175
+ end
176
+
177
+ webrat_deprecate :reloads, :reload
178
+
179
+
180
+ # Works like click_link, but only looks for the link text within a given selector
181
+ #
182
+ # Example:
183
+ # click_link_within "#user_12", "Vote"
184
+ def click_link_within(selector, link_text)
185
+ within(selector) do
186
+ click_link(link_text)
187
+ end
188
+ end
189
+
190
+ webrat_deprecate :clicks_link_within, :click_link_within
191
+
192
+ def within(selector)
193
+ scopes.push(Scope.from_scope(self, current_scope, selector))
194
+ ret = yield(current_scope)
195
+ scopes.pop
196
+ return ret
197
+ end
198
+
199
+ # Issues a GET request for a page, follows any redirects, and verifies the final page
200
+ # load was successful.
201
+ #
202
+ # Example:
203
+ # visit "/"
204
+ def visit(url = nil, http_method = :get, data = {})
205
+ request_page(url, http_method, data)
206
+ end
207
+
208
+ webrat_deprecate :visits, :visit
209
+
210
+ # Subclasses can override this to show error messages without html
211
+ def formatted_error #:nodoc:
212
+ response_body
213
+ end
214
+
215
+ def scopes #:nodoc:
216
+ @_scopes ||= []
217
+ end
218
+
219
+ def page_scope #:nodoc:
220
+ @_page_scope ||= Scope.from_page(self, response, response_body)
221
+ end
222
+
223
+ def dom
224
+ page_scope.dom
225
+ end
226
+
227
+ def xml_content_type?
228
+ false
229
+ end
230
+
231
+ def simulate
232
+ return if Webrat.configuration.mode == :selenium
233
+ yield
234
+ end
235
+
236
+ def automate
237
+ return unless Webrat.configuration.mode == :selenium
238
+ yield
239
+ end
240
+
241
+ def_delegators :current_scope, :fill_in, :fills_in
242
+ def_delegators :current_scope, :set_hidden_field
243
+ def_delegators :current_scope, :submit_form
244
+ def_delegators :current_scope, :check, :checks
245
+ def_delegators :current_scope, :uncheck, :unchecks
246
+ def_delegators :current_scope, :choose, :chooses
247
+ def_delegators :current_scope, :select, :selects
248
+ def_delegators :current_scope, :select_datetime, :selects_datetime
249
+ def_delegators :current_scope, :select_date, :selects_date
250
+ def_delegators :current_scope, :select_time, :selects_time
251
+ def_delegators :current_scope, :attach_file, :attaches_file
252
+ def_delegators :current_scope, :click_area, :clicks_area
253
+ def_delegators :current_scope, :click_link, :clicks_link
254
+ def_delegators :current_scope, :click_button, :clicks_button
255
+ def_delegators :current_scope, :field_labeled
256
+ def_delegators :current_scope, :field_by_xpath
257
+ def_delegators :current_scope, :field_with_id
258
+ def_delegators :current_scope, :select_option
259
+
260
+ private
261
+
262
+ def response_location
263
+ response.headers["Location"]
264
+ end
265
+
266
+ def current_host
267
+ URI.parse(current_url).host || "www.example.com"
268
+ end
269
+
270
+ def response_location_host
271
+ URI.parse(response_location).host || "www.example.com"
272
+ end
273
+
274
+ def reset
275
+ @elements = {}
276
+ @_scopes = nil
277
+ @_page_scope = nil
278
+ end
279
+
280
+ end
281
+ end
@@ -0,0 +1,19 @@
1
+ module Webrat
2
+
3
+ def self.hpricot_document(stringlike)
4
+ return stringlike.dom if stringlike.respond_to?(:dom)
5
+
6
+ if Hpricot::Doc === stringlike
7
+ stringlike
8
+ elsif Hpricot::Elements === stringlike
9
+ stringlike
10
+ elsif StringIO === stringlike
11
+ Hpricot(stringlike.string)
12
+ elsif stringlike.respond_to?(:body)
13
+ Hpricot(stringlike.body.to_s)
14
+ else
15
+ Hpricot(stringlike.to_s)
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,76 @@
1
+ require "webrat/core_extensions/meta_class"
2
+
3
+ module Webrat
4
+
5
+ def self.nokogiri_document(stringlike) #:nodoc:
6
+ return stringlike.dom if stringlike.respond_to?(:dom)
7
+
8
+ if Nokogiri::HTML::Document === stringlike
9
+ stringlike
10
+ elsif Nokogiri::XML::NodeSet === stringlike
11
+ stringlike
12
+ elsif StringIO === stringlike
13
+ Nokogiri::HTML(stringlike.string)
14
+ elsif stringlike.respond_to?(:body)
15
+ Nokogiri::HTML(stringlike.body.to_s)
16
+ else
17
+ Nokogiri::HTML(stringlike.to_s)
18
+ end
19
+ end
20
+
21
+ def self.html_nokogiri_document(stringlike) #:nodoc:
22
+ return stringlike.dom if stringlike.respond_to?(:dom)
23
+
24
+ if Nokogiri::HTML::Document === stringlike
25
+ stringlike
26
+ elsif Nokogiri::XML::NodeSet === stringlike
27
+ stringlike
28
+ elsif StringIO === stringlike
29
+ Nokogiri::HTML(stringlike.string)
30
+ elsif stringlike.respond_to?(:body)
31
+ Nokogiri::HTML(stringlike.body.to_s)
32
+ else
33
+ Nokogiri::HTML(stringlike.to_s)
34
+ end
35
+ end
36
+
37
+ def self.xml_nokogiri_document(stringlike) #:nodoc:
38
+ return stringlike.dom if stringlike.respond_to?(:dom)
39
+
40
+ if Nokogiri::HTML::Document === stringlike
41
+ stringlike
42
+ elsif Nokogiri::XML::NodeSet === stringlike
43
+ stringlike
44
+ elsif StringIO === stringlike
45
+ Nokogiri::XML(stringlike.string)
46
+ elsif stringlike.respond_to?(:body)
47
+ Nokogiri::XML(stringlike.body.to_s)
48
+ else
49
+ Nokogiri::XML(stringlike.to_s)
50
+ end
51
+ end
52
+
53
+ def self.define_dom_method(object, dom) #:nodoc:
54
+ object.meta_class.send(:define_method, :dom) do
55
+ dom
56
+ end
57
+ end
58
+
59
+ end
60
+
61
+
62
+ module Nokogiri #:nodoc:
63
+ module CSS #:nodoc:
64
+ class XPathVisitor #:nodoc:
65
+
66
+ def visit_pseudo_class_text(node) #:nodoc:
67
+ "@type='text'"
68
+ end
69
+
70
+ def visit_pseudo_class_password(node) #:nodoc:
71
+ "@type='password'"
72
+ end
73
+
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,24 @@
1
+ module Webrat
2
+
3
+ def self.rexml_document(stringlike)
4
+ stringlike = stringlike.body.to_s if stringlike.respond_to?(:body)
5
+
6
+ case stringlike
7
+ when REXML::Document
8
+ stringlike.root
9
+ when REXML::Node, Array
10
+ stringlike
11
+ else
12
+ begin
13
+ REXML::Document.new(stringlike.to_s).root
14
+ rescue REXML::ParseException => e
15
+ if e.message.include?("second root element")
16
+ REXML::Document.new("<fake-root-element>#{stringlike}</fake-root-element>").root
17
+ else
18
+ raise e
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,115 @@
1
+ require "webrat/core/xml/nokogiri"
2
+ require "webrat/core/xml/hpricot"
3
+ require "webrat/core/xml/rexml"
4
+
5
+ module Webrat #:nodoc:
6
+ module XML #:nodoc:
7
+
8
+ def self.document(stringlike) #:nodoc:
9
+ if Webrat.configuration.parse_with_nokogiri?
10
+ Webrat.nokogiri_document(stringlike)
11
+ else
12
+ Webrat.rexml_document(Webrat.hpricot_document(stringlike).to_html)
13
+ end
14
+ end
15
+
16
+ def self.html_document(stringlike) #:nodoc:
17
+ if Webrat.configuration.parse_with_nokogiri?
18
+ Webrat.html_nokogiri_document(stringlike)
19
+ else
20
+ Webrat.rexml_document(Webrat.hpricot_document(stringlike).to_html)
21
+ end
22
+ end
23
+
24
+ def self.xml_document(stringlike) #:nodoc:
25
+ if Webrat.configuration.parse_with_nokogiri?
26
+ Webrat.xml_nokogiri_document(stringlike)
27
+ else
28
+ Webrat.rexml_document(Webrat.hpricot_document(stringlike).to_html)
29
+ end
30
+ end
31
+
32
+ def self.to_html(element)
33
+ if Webrat.configuration.parse_with_nokogiri?
34
+ element.to_html
35
+ else
36
+ element.to_s
37
+ end
38
+ end
39
+
40
+ def self.inner_html(element)
41
+ if Webrat.configuration.parse_with_nokogiri?
42
+ element.inner_html
43
+ else
44
+ element.text
45
+ end
46
+ end
47
+
48
+ def self.all_inner_text(element)
49
+ if Webrat.configuration.parse_with_nokogiri?
50
+ element.inner_text
51
+ else
52
+ Hpricot(element.to_s).children.first.inner_text
53
+ end
54
+ end
55
+
56
+ def self.inner_text(element)
57
+ if Webrat.configuration.parse_with_nokogiri?
58
+ element.inner_text
59
+ else
60
+ if defined?(Hpricot::Doc) && element.is_a?(Hpricot::Doc)
61
+ element.inner_text
62
+ else
63
+ element.text
64
+ end
65
+ end
66
+ end
67
+
68
+ def self.xpath_to(element)
69
+ if Webrat.configuration.parse_with_nokogiri?
70
+ element.path
71
+ else
72
+ element.xpath
73
+ end
74
+ end
75
+
76
+ def self.attribute(element, attribute_name)
77
+ return element[attribute_name] if element.is_a?(Hash)
78
+
79
+ if Webrat.configuration.parse_with_nokogiri?
80
+ element[attribute_name]
81
+ else
82
+ element.attributes[attribute_name]
83
+ end
84
+ end
85
+
86
+ def self.xpath_at(*args)
87
+ xpath_search(*args).first
88
+ end
89
+
90
+ def self.css_at(*args)
91
+ css_search(*args).first
92
+ end
93
+
94
+ def self.xpath_search(element, *searches)
95
+ searches.flatten.map do |search|
96
+ if Webrat.configuration.parse_with_nokogiri?
97
+ element.xpath(search)
98
+ else
99
+ REXML::XPath.match(element, search)
100
+ end
101
+ end.flatten.compact
102
+ end
103
+
104
+ def self.css_search(element, *searches) #:nodoc:
105
+ xpath_search(element, css_to_xpath(*searches))
106
+ end
107
+
108
+ def self.css_to_xpath(*selectors)
109
+ selectors.map do |rule|
110
+ Nokogiri::CSS.xpath_for(rule, :prefix => ".//")
111
+ end.flatten.uniq
112
+ end
113
+
114
+ end
115
+ end
@@ -0,0 +1,14 @@
1
+ require "webrat/core/configuration"
2
+ require "webrat/core/xml"
3
+ require "webrat/core/xml/nokogiri"
4
+ require "webrat/core/logging"
5
+ require "webrat/core/elements/form"
6
+ require "webrat/core/scope"
7
+ require "webrat/core/elements/link"
8
+ require "webrat/core/elements/area"
9
+ require "webrat/core/elements/label"
10
+ require "webrat/core/elements/select_option"
11
+ require "webrat/core/session"
12
+ require "webrat/core/methods"
13
+ require "webrat/core/matchers"
14
+ require "webrat/core/save_and_open_page"
@@ -0,0 +1,58 @@
1
+ class Object #:nodoc:
2
+ # An object is blank if it's false, empty, or a whitespace string.
3
+ # For example, "", " ", +nil+, [], and {} are blank.
4
+ #
5
+ # This simplifies
6
+ #
7
+ # if !address.nil? && !address.empty?
8
+ #
9
+ # to
10
+ #
11
+ # if !address.blank?
12
+ def blank?
13
+ respond_to?(:empty?) ? empty? : !self
14
+ end
15
+
16
+ # An object is present if it's not blank.
17
+ def present?
18
+ !blank?
19
+ end
20
+ end
21
+
22
+ class NilClass #:nodoc:
23
+ def blank?
24
+ true
25
+ end
26
+ end
27
+
28
+ class FalseClass #:nodoc:
29
+ def blank?
30
+ true
31
+ end
32
+ end
33
+
34
+ class TrueClass #:nodoc:
35
+ def blank?
36
+ false
37
+ end
38
+ end
39
+
40
+ class Array #:nodoc:
41
+ alias_method :blank?, :empty?
42
+ end
43
+
44
+ class Hash #:nodoc:
45
+ alias_method :blank?, :empty?
46
+ end
47
+
48
+ class String #:nodoc:
49
+ def blank?
50
+ self !~ /\S/
51
+ end
52
+ end
53
+
54
+ class Numeric #:nodoc:
55
+ def blank?
56
+ false
57
+ end
58
+ end
@@ -0,0 +1,8 @@
1
+ class Module #:nodoc:
2
+ def webrat_deprecate(old_method_name, new_method_name)
3
+ define_method old_method_name do |*args|
4
+ warn "#{old_method_name} is deprecated. Use #{new_method_name} instead."
5
+ __send__(new_method_name, *args)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,12 @@
1
+ class Array #:nodoc:
2
+
3
+ def detect_mapped
4
+ each do |element|
5
+ result = yield element
6
+ return result if result
7
+ end
8
+
9
+ return nil
10
+ end
11
+
12
+ end
@@ -0,0 +1,6 @@
1
+ class ::Object #:nodoc:
2
+ def meta_class
3
+ class << self; self end
4
+ end
5
+ end
6
+
@@ -0,0 +1,5 @@
1
+ class NilClass #:nodoc:
2
+ def to_param
3
+ nil
4
+ end
5
+ end
@@ -0,0 +1,27 @@
1
+ class TCPSocket
2
+
3
+ def self.wait_for_service_with_timeout(options)
4
+ start_time = Time.now
5
+
6
+ until listening_service?(options)
7
+ verbose_wait
8
+
9
+ if options[:timeout] && (Time.now > start_time + options[:timeout])
10
+ raise SocketError.new("Socket did not open within #{options[:timeout]} seconds")
11
+ end
12
+ end
13
+ end
14
+
15
+ def self.wait_for_service_termination_with_timeout(options)
16
+ start_time = Time.now
17
+
18
+ while listening_service?(options)
19
+ verbose_wait
20
+
21
+ if options[:timeout] && (Time.now > start_time + options[:timeout])
22
+ raise SocketError.new("Socket did not terminate within #{options[:timeout]} seconds")
23
+ end
24
+ end
25
+ end
26
+
27
+ end