futuresinc-webrat 0.4.4.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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