mechanize 0.7.8 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of mechanize might be problematic. Click here for more details.

Files changed (96) hide show
  1. data/History.txt +14 -0
  2. data/Manifest.txt +30 -5
  3. data/README.txt +5 -5
  4. data/Rakefile +6 -0
  5. data/{eg → examples}/flickr_upload.rb +0 -0
  6. data/{eg → examples}/mech-dump.rb +0 -0
  7. data/{eg → examples}/proxy_req.rb +0 -0
  8. data/{eg → examples}/rubyforge.rb +0 -0
  9. data/{eg → examples}/spider.rb +0 -0
  10. data/lib/www/mechanize.rb +183 -404
  11. data/lib/www/mechanize/chain.rb +34 -0
  12. data/lib/www/mechanize/chain/auth_headers.rb +79 -0
  13. data/lib/www/mechanize/chain/body_decoding_handler.rb +43 -0
  14. data/lib/www/mechanize/chain/connection_resolver.rb +78 -0
  15. data/lib/www/mechanize/chain/custom_headers.rb +23 -0
  16. data/lib/www/mechanize/chain/handler.rb +9 -0
  17. data/lib/www/mechanize/chain/header_resolver.rb +47 -0
  18. data/lib/www/mechanize/chain/parameter_resolver.rb +23 -0
  19. data/lib/www/mechanize/chain/post_connect_hook.rb +0 -0
  20. data/lib/www/mechanize/chain/pre_connect_hook.rb +22 -0
  21. data/lib/www/mechanize/chain/request_resolver.rb +28 -0
  22. data/lib/www/mechanize/chain/response_body_parser.rb +40 -0
  23. data/lib/www/mechanize/chain/response_header_handler.rb +50 -0
  24. data/lib/www/mechanize/chain/response_reader.rb +41 -0
  25. data/lib/www/mechanize/chain/ssl_resolver.rb +36 -0
  26. data/lib/www/mechanize/chain/uri_resolver.rb +56 -0
  27. data/lib/www/mechanize/cookie.rb +1 -1
  28. data/lib/www/mechanize/file_response.rb +60 -0
  29. data/lib/www/mechanize/form.rb +12 -4
  30. data/lib/www/mechanize/form/field.rb +2 -2
  31. data/lib/www/mechanize/form/file_upload.rb +1 -1
  32. data/lib/www/mechanize/form/option.rb +1 -1
  33. data/lib/www/mechanize/list.rb +4 -0
  34. data/lib/www/mechanize/page.rb +20 -10
  35. data/lib/www/mechanize/util.rb +29 -0
  36. data/mechanize.gemspec +4 -4
  37. data/test/chain/test_argument_validator.rb +14 -0
  38. data/test/chain/test_custom_headers.rb +18 -0
  39. data/test/chain/test_parameter_resolver.rb +35 -0
  40. data/test/chain/test_request_resolver.rb +29 -0
  41. data/test/chain/test_response_reader.rb +24 -0
  42. data/test/helper.rb +3 -1
  43. data/test/servlets.rb +43 -0
  44. data/test/test_authenticate.rb +13 -12
  45. data/test/test_bad_links.rb +1 -1
  46. data/test/test_blank_form.rb +1 -1
  47. data/test/test_checkboxes.rb +1 -1
  48. data/test/test_content_type.rb +1 -1
  49. data/test/test_cookie_class.rb +1 -1
  50. data/test/test_cookie_jar.rb +1 -1
  51. data/test/test_cookies.rb +1 -1
  52. data/test/test_encoded_links.rb +1 -1
  53. data/test/test_errors.rb +1 -1
  54. data/test/test_follow_meta.rb +1 -1
  55. data/test/test_form_action.rb +1 -1
  56. data/test/test_form_as_hash.rb +1 -1
  57. data/test/test_form_button.rb +22 -17
  58. data/test/test_form_no_inputname.rb +1 -1
  59. data/test/test_forms.rb +2 -1
  60. data/test/test_frames.rb +1 -1
  61. data/test/test_get_headers.rb +1 -1
  62. data/test/test_gzipping.rb +1 -1
  63. data/test/test_hash_api.rb +17 -14
  64. data/test/test_history.rb +1 -1
  65. data/test/test_history_added.rb +1 -1
  66. data/test/test_html_unscape_forms.rb +1 -1
  67. data/test/test_if_modified_since.rb +1 -1
  68. data/test/test_keep_alive.rb +1 -1
  69. data/test/test_links.rb +1 -1
  70. data/test/test_mech.rb +18 -11
  71. data/test/test_mechanize_file.rb +1 -1
  72. data/test/test_multi_select.rb +1 -1
  73. data/test/test_no_attributes.rb +1 -1
  74. data/test/test_option.rb +2 -1
  75. data/test/test_page.rb +1 -1
  76. data/test/test_pluggable_parser.rb +1 -1
  77. data/test/test_post_form.rb +1 -1
  78. data/test/test_pretty_print.rb +1 -1
  79. data/test/test_radiobutton.rb +1 -1
  80. data/test/test_redirect_limit_reached.rb +1 -1
  81. data/test/test_referer.rb +1 -1
  82. data/test/test_relative_links.rb +1 -1
  83. data/test/test_response_code.rb +7 -1
  84. data/test/test_save_file.rb +1 -1
  85. data/test/test_scheme.rb +44 -0
  86. data/test/test_select.rb +1 -1
  87. data/test/test_select_all.rb +1 -1
  88. data/test/test_select_none.rb +1 -1
  89. data/test/test_select_noopts.rb +1 -1
  90. data/test/test_set_fields.rb +1 -1
  91. data/test/test_ssl_server.rb +1 -1
  92. data/test/test_subclass.rb +4 -11
  93. data/test/test_textarea.rb +1 -1
  94. data/test/test_upload.rb +1 -1
  95. data/test/test_verbs.rb +22 -0
  96. metadata +39 -7
@@ -0,0 +1,50 @@
1
+ module WWW
2
+ class Mechanize
3
+ class Chain
4
+ class ResponseHeaderHandler
5
+ include WWW::Handler
6
+
7
+ def initialize(cookie_jar, connection_cache)
8
+ @cookie_jar = cookie_jar
9
+ @connection_cache = connection_cache
10
+ end
11
+
12
+ def handle(ctx, params)
13
+ response = params[:response]
14
+ uri = params[:uri]
15
+ page = params[:page]
16
+ cache_obj = (@connection_cache["#{uri.host}:#{uri.port}"] ||= {
17
+ :connection => nil,
18
+ :keep_alive_options => {},
19
+ })
20
+
21
+ # If the server sends back keep alive options, save them
22
+ if keep_alive_info = response['keep-alive']
23
+ keep_alive_info.split(/,\s*/).each do |option|
24
+ k, v = option.split(/=/)
25
+ cache_obj[:keep_alive_options] ||= {}
26
+ cache_obj[:keep_alive_options][k.intern] = v
27
+ end
28
+ end
29
+
30
+ if page.is_a?(Page) && page.body =~ /Set-Cookie/
31
+ page.search('//meta[@http-equiv="Set-Cookie"]').each do |meta|
32
+ Cookie::parse(uri, meta['content']) { |c|
33
+ Mechanize.log.debug("saved cookie: #{c}") if Mechanize.log
34
+ @cookie_jar.add(uri, c)
35
+ }
36
+ end
37
+ end
38
+
39
+ (response.get_fields('Set-Cookie')||[]).each do |cookie|
40
+ Cookie::parse(uri, cookie) { |c|
41
+ Mechanize.log.debug("saved cookie: #{c}") if Mechanize.log
42
+ @cookie_jar.add(uri, c)
43
+ }
44
+ end
45
+ super
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,41 @@
1
+ module WWW
2
+ class Mechanize
3
+ class Chain
4
+ class ResponseReader
5
+ include WWW::Handler
6
+
7
+ def initialize(response)
8
+ @response = response
9
+ end
10
+
11
+ def handle(ctx, params)
12
+ params[:response] = @response
13
+ body = StringIO.new
14
+ total = 0
15
+ @response.read_body { |part|
16
+ total += part.length
17
+ body.write(part)
18
+ Mechanize.log.debug("Read #{total} bytes") if Mechanize.log
19
+ }
20
+ body.rewind
21
+
22
+ res_klass = Net::HTTPResponse::CODE_TO_OBJ[@response.code.to_s]
23
+ raise ResponseCodeError.new(@response) unless res_klass
24
+
25
+ # Net::HTTP ignores EOFError if Content-length is given, so we emulate it here.
26
+ unless res_klass <= Net::HTTPRedirection
27
+ raise EOFError if @response.content_length() && @response.content_length() != total
28
+ end
29
+
30
+ response.each_header { |k,v|
31
+ Mechanize.log.debug("response-header: #{ k } => #{ v }")
32
+ } if Mechanize.log
33
+
34
+ params[:response_body] = body
35
+ params[:res_klass] = res_klass
36
+ super
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,36 @@
1
+ module WWW
2
+ class Mechanize
3
+ class Chain
4
+ class SSLResolver
5
+ include WWW::Handler
6
+
7
+ def initialize(ca_file, verify_callback, cert, key, pass)
8
+ @ca_file = ca_file
9
+ @verify_callback = verify_callback
10
+ @cert = cert
11
+ @key = key
12
+ @pass = pass
13
+ end
14
+
15
+ def handle(ctx, params)
16
+ uri = params[:uri]
17
+ http_obj = params[:connection]
18
+ if uri.scheme == 'https' && ! http_obj.started?
19
+ http_obj.use_ssl = true
20
+ http_obj.verify_mode = OpenSSL::SSL::VERIFY_NONE
21
+ if @ca_file
22
+ http_obj.ca_file = @ca_file
23
+ http_obj.verify_mode = OpenSSL::SSL::VERIFY_PEER
24
+ http_obj.verify_callback = @verify_callback if @verify_callback
25
+ end
26
+ if @cert && @key
27
+ http_obj.cert = OpenSSL::X509::Certificate.new(::File.read(@cert))
28
+ http_obj.key = OpenSSL::PKey::RSA.new(::File.read(@key), @pass)
29
+ end
30
+ end
31
+ super
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,56 @@
1
+ module WWW
2
+ class Mechanize
3
+ class Chain
4
+ class URIResolver
5
+ include WWW::Handler
6
+
7
+ def initialize(scheme_handlers)
8
+ @scheme_handlers = scheme_handlers
9
+ end
10
+
11
+ def handle(ctx, params)
12
+ raise ArgumentError.new('uri must be specified') unless params[:uri]
13
+ uri = params[:uri]
14
+ referer = params[:referer]
15
+ unless uri.is_a?(URI)
16
+ uri = uri.to_s.strip.gsub(/[^#{0.chr}-#{126.chr}]/) { |match|
17
+ sprintf('%%%X', match.unpack($KCODE == 'UTF8' ? 'U' : 'c')[0])
18
+ }
19
+
20
+ uri = URI.parse(
21
+ Util.html_unescape(
22
+ uri.split(/(?:%[0-9A-Fa-f]{2})+|#/).zip(
23
+ uri.scan(/(?:%[0-9A-Fa-f]{2})+|#/)
24
+ ).map { |x,y|
25
+ "#{URI.escape(x)}#{y}"
26
+ }.join('')
27
+ )
28
+ )
29
+ end
30
+ uri = @scheme_handlers[
31
+ uri.relative? ? 'relative' : uri.scheme.downcase
32
+ ].call(uri, params[:referer])
33
+ uri.path = '/' if uri.path.length == 0
34
+
35
+ if uri.relative?
36
+ raise 'need absolute URL' unless referer && referer.uri
37
+ base = referer.respond_to?(:bases) ? referer.bases.last : nil
38
+ uri = ((base && base.uri && base.uri.absolute?) ?
39
+ base.uri :
40
+ referer.uri) + uri
41
+ uri = referer.uri + uri
42
+ # Strip initial "/.." bits from the path
43
+ uri.path.sub!(/^(\/\.\.)+(?=\/)/, '')
44
+ end
45
+
46
+ unless ['http', 'https', 'file'].include?(uri.scheme.downcase)
47
+ raise "unsupported scheme: #{uri.scheme}"
48
+ end
49
+ params[:uri] = uri
50
+
51
+ super
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -5,7 +5,7 @@ module WWW
5
5
  class Mechanize
6
6
  # This class is used to represent an HTTP Cookie.
7
7
  class Cookie < WEBrick::Cookie
8
- def self.parse(uri, str, log = nil)
8
+ def self.parse(uri, str, log = Mechanize.log)
9
9
  return str.split(/,(?=[^;,]*=)|,$/).collect { |c|
10
10
  cookie_elem = c.split(/;+/)
11
11
  first_elem = cookie_elem.shift
@@ -0,0 +1,60 @@
1
+ module WWW
2
+ class Mechanize
3
+ ###
4
+ # Fake response for dealing with file:/// requests
5
+ class FileResponse
6
+ def initialize(file_path)
7
+ @file_path = file_path
8
+ end
9
+
10
+ def read_body
11
+ if ::File.exists?(@file_path)
12
+ if directory?
13
+ yield dir_body
14
+ else
15
+ yield ::File.read(@file_path)
16
+ end
17
+ else
18
+ yield ''
19
+ end
20
+ end
21
+
22
+ def code
23
+ ::File.exists?(@file_path) ? 200 : 400
24
+ end
25
+
26
+ def content_length
27
+ return dir_body.length if directory?
28
+ ::File.exists?(@file_path) ? ::File.stat(@file_path).size : 0
29
+ end
30
+
31
+ def [](key)
32
+ return nil unless key.downcase == 'content-type'
33
+ return 'text/html' if directory?
34
+ return 'text/html' if ['.html', '.xhtml'].any? { |extn|
35
+ @file_path =~ /#{extn}$/
36
+ }
37
+ nil
38
+ end
39
+
40
+ def each
41
+ end
42
+
43
+ def get_fields(key)
44
+ []
45
+ end
46
+
47
+ private
48
+ def dir_body
49
+ '<html><body>' +
50
+ Dir[::File.join(@file_path, '*')].map { |f|
51
+ "<a href=\"file://#{f}\">#{::File.basename(f)}</a>"
52
+ }.join("\n") + '</body></html>'
53
+ end
54
+
55
+ def directory?
56
+ ::File.directory?(@file_path)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -36,7 +36,7 @@ module WWW
36
36
  def initialize(node, mech=nil, page=nil)
37
37
  @enctype = node['enctype'] || 'application/x-www-form-urlencoded'
38
38
  @form_node = node
39
- @action = Mechanize.html_unescape(node['action'])
39
+ @action = Util.html_unescape(node['action'])
40
40
  @method = (node['method'] || 'GET').upcase
41
41
  @name = node['name']
42
42
  @clicked_buttons = []
@@ -201,7 +201,7 @@ module WWW
201
201
  params.collect { |p| "--#{boundary}\r\n#{p}" }.join('') +
202
202
  "--#{boundary}--\r\n"
203
203
  else
204
- WWW::Mechanize.build_query_string(query_params)
204
+ WWW::Mechanize::Util.build_query_string(query_params)
205
205
  end
206
206
  end
207
207
 
@@ -225,9 +225,9 @@ module WWW
225
225
  next if name.nil? && !(type == 'submit' || type =='button')
226
226
  case type
227
227
  when 'radio'
228
- @radiobuttons << RadioButton.new(node['name'], node['value'], node.has_attribute?('checked'), self)
228
+ @radiobuttons << RadioButton.new(node['name'], node['value'], !!node['checked'], self)
229
229
  when 'checkbox'
230
- @checkboxes << CheckBox.new(node['name'], node['value'], node.has_attribute?('checked'), self)
230
+ @checkboxes << CheckBox.new(node['name'], node['value'], !!node['checked'], self)
231
231
  when 'file'
232
232
  @file_uploads << FileUpload.new(node['name'], nil)
233
233
  when 'submit'
@@ -256,6 +256,14 @@ module WWW
256
256
  @fields << SelectList.new(node['name'], node)
257
257
  end
258
258
  end
259
+
260
+ # Find all submit button tags
261
+ # FIXME: what can I do with the reset buttons?
262
+ form_node.search('//button').each do |node|
263
+ type = (node['type'] || 'submit').downcase
264
+ next if type == 'reset'
265
+ @buttons << Button.new(node['name'], node['value'])
266
+ end
259
267
  end
260
268
 
261
269
  def rand_string(len = 10)
@@ -11,9 +11,9 @@ module WWW
11
11
  attr_accessor :name, :value
12
12
 
13
13
  def initialize(name, value)
14
- @name = Mechanize.html_unescape(name)
14
+ @name = Util.html_unescape(name)
15
15
  @value = if value.is_a? String
16
- Mechanize.html_unescape(value)
16
+ Util.html_unescape(value)
17
17
  else
18
18
  value
19
19
  end
@@ -14,7 +14,7 @@ module WWW
14
14
  alias :file_data= :value=
15
15
 
16
16
  def initialize(name, file_name)
17
- @file_name = Mechanize.html_unescape(file_name)
17
+ @file_name = Util.html_unescape(file_name)
18
18
  @file_data = nil
19
19
  super(name, @file_data)
20
20
  end
@@ -14,7 +14,7 @@ module WWW
14
14
 
15
15
  def initialize(node, select_list)
16
16
  @text = node.inner_text
17
- @value = Mechanize.html_unescape(node['value'] || node.inner_text)
17
+ @value = Util.html_unescape(node['value'] || node.inner_text)
18
18
  @selected = node.has_attribute? 'selected'
19
19
  @select_list = select_list # The select list this option belongs to
20
20
  end
@@ -53,6 +53,10 @@ module WWW
53
53
 
54
54
  alias :and :with
55
55
 
56
+ def respond_to?(method_sym)
57
+ first.respond_to?(method_sym)
58
+ end
59
+
56
60
  def method_missing(meth_sym, *args)
57
61
  if length > 0
58
62
  return first.send(meth_sym) if args.empty?
@@ -27,7 +27,7 @@ module WWW
27
27
  @mech ||= mech
28
28
 
29
29
  raise Mechanize::ContentTypeError.new(response['content-type']) unless
30
- content_type() =~ /^(text\/html)|(application\/xhtml\+xml)/
30
+ response['content-type'] =~ /^(text\/html)|(application\/xhtml\+xml)/
31
31
 
32
32
  @parser = @links = @forms = @meta = @bases = @frames = @iframes = nil
33
33
  end
@@ -58,15 +58,25 @@ module WWW
58
58
  # page.form(:action => '/post/login.php') do |f|
59
59
  # ...
60
60
  # end
61
- def form_with(criteria)
62
- criteria = {:name => criteria} if String === criteria
63
- f = forms.find do |form|
64
- criteria.all? { |k,v| form.send(k) == v }
65
- end
66
- yield f if block_given?
67
- f
61
+ [:form, :link, :base, :frame, :iframe].each do |type|
62
+ eval(<<-eomethod)
63
+ def #{type}s_with(criteria)
64
+ criteria = {:name => criteria} if String === criteria
65
+ f = #{type}s.find_all do |thing|
66
+ criteria.all? { |k,v| v === thing.send(k) }
67
+ end
68
+ yield f if block_given?
69
+ f
70
+ end
71
+
72
+ def #{type}_with(criteria)
73
+ f = #{type}s_with(criteria).first
74
+ yield f if block_given?
75
+ f
76
+ end
77
+ alias :#{type} :#{type}_with
78
+ eomethod
68
79
  end
69
- alias :form :form_with
70
80
 
71
81
  def links
72
82
  @links ||= WWW::Mechanize::List.new(
@@ -82,7 +92,7 @@ module WWW
82
92
  @forms ||= WWW::Mechanize::List.new(
83
93
  search('//form').map do |html_form|
84
94
  form = Form.new(html_form, @mech, self)
85
- form.action ||= @uri
95
+ form.action ||= @uri.to_s
86
96
  form
87
97
  end
88
98
  )
@@ -0,0 +1,29 @@
1
+ module WWW
2
+ class Mechanize
3
+ class Util
4
+ class << self
5
+ def build_query_string(parameters)
6
+ parameters.map { |k,v|
7
+ k &&
8
+ [WEBrick::HTTPUtils.escape_form(k.to_s),
9
+ WEBrick::HTTPUtils.escape_form(v.to_s)].join("=")
10
+ }.compact.join('&')
11
+ end
12
+
13
+ def html_unescape(s)
14
+ return s unless s
15
+ s.gsub(/&(\w+|#[0-9]+);/) { |match|
16
+ number = case match
17
+ when /&(\w+);/
18
+ Mechanize.html_parser::NamedCharacters[$1]
19
+ when /&#([0-9]+);/
20
+ $1.to_i
21
+ end
22
+
23
+ number ? ([number].pack('U') rescue match) : match
24
+ }
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
data/mechanize.gemspec CHANGED
@@ -1,14 +1,14 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{mechanize}
3
- s.version = "0.7.7.20080826145538"
3
+ s.version = "0.7.8.20080916154215"
4
4
 
5
5
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
6
  s.authors = ["Aaron Patterson"]
7
- s.date = %q{2008-08-26}
7
+ s.date = %q{2008-09-16}
8
8
  s.description = %q{The Mechanize library is used for automating interaction with websites. Mechanize automatically stores and sends cookies, follows redirects, can follow links, and submit forms. Form fields can be populated and submitted. Mechanize also keeps track of the sites that you have visited as a history.}
9
9
  s.email = %q{aaronp@rubyforge.org}
10
10
  s.extra_rdoc_files = ["EXAMPLES.txt", "FAQ.txt", "GUIDE.txt", "History.txt", "LICENSE.txt", "Manifest.txt", "NOTES.txt", "README.txt"]
11
- s.files = ["EXAMPLES.txt", "FAQ.txt", "GUIDE.txt", "History.txt", "LICENSE.txt", "Manifest.txt", "NOTES.txt", "README.txt", "Rakefile", "eg/flickr_upload.rb", "eg/mech-dump.rb", "eg/proxy_req.rb", "eg/rubyforge.rb", "eg/spider.rb", "lib/mechanize.rb", "lib/www/mechanize.rb", "lib/www/mechanize/content_type_error.rb", "lib/www/mechanize/cookie.rb", "lib/www/mechanize/cookie_jar.rb", "lib/www/mechanize/file.rb", "lib/www/mechanize/file_saver.rb", "lib/www/mechanize/form.rb", "lib/www/mechanize/form/button.rb", "lib/www/mechanize/form/check_box.rb", "lib/www/mechanize/form/field.rb", "lib/www/mechanize/form/file_upload.rb", "lib/www/mechanize/form/image_button.rb", "lib/www/mechanize/form/multi_select_list.rb", "lib/www/mechanize/form/option.rb", "lib/www/mechanize/form/radio_button.rb", "lib/www/mechanize/form/select_list.rb", "lib/www/mechanize/headers.rb", "lib/www/mechanize/history.rb", "lib/www/mechanize/inspect.rb", "lib/www/mechanize/list.rb", "lib/www/mechanize/monkey_patch.rb", "lib/www/mechanize/page.rb", "lib/www/mechanize/page/base.rb", "lib/www/mechanize/page/frame.rb", "lib/www/mechanize/page/link.rb", "lib/www/mechanize/page/meta.rb", "lib/www/mechanize/pluggable_parsers.rb", "lib/www/mechanize/redirect_limit_reached_error.rb", "lib/www/mechanize/response_code_error.rb", "lib/www/mechanize/unsupported_scheme_error.rb", "mechanize.gemspec", "test/data/htpasswd", "test/data/server.crt", "test/data/server.csr", "test/data/server.key", "test/data/server.pem", "test/helper.rb", "test/htdocs/alt_text.html", "test/htdocs/bad_form_test.html", "test/htdocs/button.jpg", "test/htdocs/empty_form.html", "test/htdocs/file_upload.html", "test/htdocs/find_link.html", "test/htdocs/form_multi_select.html", "test/htdocs/form_multival.html", "test/htdocs/form_no_action.html", "test/htdocs/form_no_input_name.html", "test/htdocs/form_select.html", "test/htdocs/form_select_all.html", "test/htdocs/form_select_none.html", "test/htdocs/form_select_noopts.html", "test/htdocs/form_set_fields.html", "test/htdocs/form_test.html", "test/htdocs/frame_test.html", "test/htdocs/google.html", "test/htdocs/iframe_test.html", "test/htdocs/index.html", "test/htdocs/link with space.html", "test/htdocs/meta_cookie.html", "test/htdocs/no_title_test.html", "test/htdocs/relative/tc_relative_links.html", "test/htdocs/tc_bad_links.html", "test/htdocs/tc_base_link.html", "test/htdocs/tc_blank_form.html", "test/htdocs/tc_checkboxes.html", "test/htdocs/tc_encoded_links.html", "test/htdocs/tc_follow_meta.html", "test/htdocs/tc_form_action.html", "test/htdocs/tc_links.html", "test/htdocs/tc_no_attributes.html", "test/htdocs/tc_pretty_print.html", "test/htdocs/tc_radiobuttons.html", "test/htdocs/tc_referer.html", "test/htdocs/tc_relative_links.html", "test/htdocs/tc_textarea.html", "test/htdocs/unusual______.html", "test/servlets.rb", "test/ssl_server.rb", "test/test_authenticate.rb", "test/test_bad_links.rb", "test/test_blank_form.rb", "test/test_checkboxes.rb", "test/test_content_type.rb", "test/test_cookie_class.rb", "test/test_cookie_jar.rb", "test/test_cookies.rb", "test/test_encoded_links.rb", "test/test_errors.rb", "test/test_follow_meta.rb", "test/test_form_action.rb", "test/test_form_as_hash.rb", "test/test_form_button.rb", "test/test_form_no_inputname.rb", "test/test_forms.rb", "test/test_frames.rb", "test/test_get_headers.rb", "test/test_gzipping.rb", "test/test_hash_api.rb", "test/test_history.rb", "test/test_history_added.rb", "test/test_html_unscape_forms.rb", "test/test_if_modified_since.rb", "test/test_keep_alive.rb", "test/test_links.rb", "test/test_mech.rb", "test/test_mechanize_file.rb", "test/test_multi_select.rb", "test/test_no_attributes.rb", "test/test_option.rb", "test/test_page.rb", "test/test_pluggable_parser.rb", "test/test_post_form.rb", "test/test_pretty_print.rb", "test/test_radiobutton.rb", "test/test_redirect_limit_reached.rb", "test/test_referer.rb", "test/test_relative_links.rb", "test/test_response_code.rb", "test/test_save_file.rb", "test/test_select.rb", "test/test_select_all.rb", "test/test_select_none.rb", "test/test_select_noopts.rb", "test/test_set_fields.rb", "test/test_ssl_server.rb", "test/test_subclass.rb", "test/test_textarea.rb", "test/test_upload.rb"]
11
+ s.files = ["EXAMPLES.txt", "FAQ.txt", "GUIDE.txt", "History.txt", "LICENSE.txt", "Manifest.txt", "NOTES.txt", "README.txt", "Rakefile", "eg/flickr_upload.rb", "eg/mech-dump.rb", "eg/proxy_req.rb", "eg/rubyforge.rb", "eg/spider.rb", "lib/mechanize.rb", "lib/www/mechanize.rb", "lib/www/mechanize/chain.rb", "lib/www/mechanize/chain/auth_headers.rb", "lib/www/mechanize/chain/body_decoding_handler.rb", "lib/www/mechanize/chain/connection_resolver.rb", "lib/www/mechanize/chain/custom_headers.rb", "lib/www/mechanize/chain/handler.rb", "lib/www/mechanize/chain/header_resolver.rb", "lib/www/mechanize/chain/parameter_resolver.rb", "lib/www/mechanize/chain/post_connect_hook.rb", "lib/www/mechanize/chain/pre_connect_hook.rb", "lib/www/mechanize/chain/request_resolver.rb", "lib/www/mechanize/chain/response_body_parser.rb", "lib/www/mechanize/chain/response_header_handler.rb", "lib/www/mechanize/chain/response_reader.rb", "lib/www/mechanize/chain/ssl_resolver.rb", "lib/www/mechanize/chain/uri_resolver.rb", "lib/www/mechanize/content_type_error.rb", "lib/www/mechanize/cookie.rb", "lib/www/mechanize/cookie_jar.rb", "lib/www/mechanize/file.rb", "lib/www/mechanize/file_response.rb", "lib/www/mechanize/file_saver.rb", "lib/www/mechanize/form.rb", "lib/www/mechanize/form/button.rb", "lib/www/mechanize/form/check_box.rb", "lib/www/mechanize/form/field.rb", "lib/www/mechanize/form/file_upload.rb", "lib/www/mechanize/form/image_button.rb", "lib/www/mechanize/form/multi_select_list.rb", "lib/www/mechanize/form/option.rb", "lib/www/mechanize/form/radio_button.rb", "lib/www/mechanize/form/select_list.rb", "lib/www/mechanize/headers.rb", "lib/www/mechanize/history.rb", "lib/www/mechanize/inspect.rb", "lib/www/mechanize/list.rb", "lib/www/mechanize/monkey_patch.rb", "lib/www/mechanize/page.rb", "lib/www/mechanize/page/base.rb", "lib/www/mechanize/page/frame.rb", "lib/www/mechanize/page/link.rb", "lib/www/mechanize/page/meta.rb", "lib/www/mechanize/pluggable_parsers.rb", "lib/www/mechanize/redirect_limit_reached_error.rb", "lib/www/mechanize/response_code_error.rb", "lib/www/mechanize/unsupported_scheme_error.rb", "lib/www/mechanize/util.rb", "mechanize.gemspec", "test/chain/test_argument_validator.rb", "test/chain/test_custom_headers.rb", "test/chain/test_parameter_resolver.rb", "test/chain/test_request_resolver.rb", "test/chain/test_response_reader.rb", "test/data/htpasswd", "test/data/server.crt", "test/data/server.csr", "test/data/server.key", "test/data/server.pem", "test/helper.rb", "test/htdocs/alt_text.html", "test/htdocs/bad_form_test.html", "test/htdocs/button.jpg", "test/htdocs/empty_form.html", "test/htdocs/file_upload.html", "test/htdocs/find_link.html", "test/htdocs/form_multi_select.html", "test/htdocs/form_multival.html", "test/htdocs/form_no_action.html", "test/htdocs/form_no_input_name.html", "test/htdocs/form_select.html", "test/htdocs/form_select_all.html", "test/htdocs/form_select_none.html", "test/htdocs/form_select_noopts.html", "test/htdocs/form_set_fields.html", "test/htdocs/form_test.html", "test/htdocs/frame_test.html", "test/htdocs/google.html", "test/htdocs/iframe_test.html", "test/htdocs/index.html", "test/htdocs/link with space.html", "test/htdocs/meta_cookie.html", "test/htdocs/no_title_test.html", "test/htdocs/relative/tc_relative_links.html", "test/htdocs/tc_bad_links.html", "test/htdocs/tc_base_link.html", "test/htdocs/tc_blank_form.html", "test/htdocs/tc_checkboxes.html", "test/htdocs/tc_encoded_links.html", "test/htdocs/tc_follow_meta.html", "test/htdocs/tc_form_action.html", "test/htdocs/tc_links.html", "test/htdocs/tc_no_attributes.html", "test/htdocs/tc_pretty_print.html", "test/htdocs/tc_radiobuttons.html", "test/htdocs/tc_referer.html", "test/htdocs/tc_relative_links.html", "test/htdocs/tc_textarea.html", "test/htdocs/unusual______.html", "test/servlets.rb", "test/ssl_server.rb", "test/test_authenticate.rb", "test/test_bad_links.rb", "test/test_blank_form.rb", "test/test_checkboxes.rb", "test/test_content_type.rb", "test/test_cookie_class.rb", "test/test_cookie_jar.rb", "test/test_cookies.rb", "test/test_encoded_links.rb", "test/test_errors.rb", "test/test_follow_meta.rb", "test/test_form_action.rb", "test/test_form_as_hash.rb", "test/test_form_button.rb", "test/test_form_no_inputname.rb", "test/test_forms.rb", "test/test_frames.rb", "test/test_get_headers.rb", "test/test_gzipping.rb", "test/test_hash_api.rb", "test/test_history.rb", "test/test_history_added.rb", "test/test_html_unscape_forms.rb", "test/test_if_modified_since.rb", "test/test_keep_alive.rb", "test/test_links.rb", "test/test_mech.rb", "test/test_mechanize_file.rb", "test/test_multi_select.rb", "test/test_no_attributes.rb", "test/test_option.rb", "test/test_page.rb", "test/test_pluggable_parser.rb", "test/test_post_form.rb", "test/test_pretty_print.rb", "test/test_radiobutton.rb", "test/test_redirect_limit_reached.rb", "test/test_referer.rb", "test/test_relative_links.rb", "test/test_response_code.rb", "test/test_save_file.rb", "test/test_scheme.rb", "test/test_select.rb", "test/test_select_all.rb", "test/test_select_none.rb", "test/test_select_noopts.rb", "test/test_set_fields.rb", "test/test_ssl_server.rb", "test/test_subclass.rb", "test/test_textarea.rb", "test/test_upload.rb", "test/test_verbs.rb"]
12
12
  s.has_rdoc = true
13
13
  s.homepage = %q{ http://mechanize.rubyforge.org/}
14
14
  s.rdoc_options = ["--main", "README.txt"]
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
16
16
  s.rubyforge_project = %q{mechanize}
17
17
  s.rubygems_version = %q{1.2.0}
18
18
  s.summary = %q{Mechanize provides automated web-browsing}
19
- s.test_files = ["test/test_authenticate.rb", "test/test_bad_links.rb", "test/test_blank_form.rb", "test/test_checkboxes.rb", "test/test_content_type.rb", "test/test_cookie_class.rb", "test/test_cookie_jar.rb", "test/test_cookies.rb", "test/test_encoded_links.rb", "test/test_errors.rb", "test/test_follow_meta.rb", "test/test_form_action.rb", "test/test_form_as_hash.rb", "test/test_form_button.rb", "test/test_form_no_inputname.rb", "test/test_forms.rb", "test/test_frames.rb", "test/test_get_headers.rb", "test/test_gzipping.rb", "test/test_hash_api.rb", "test/test_history.rb", "test/test_history_added.rb", "test/test_html_unscape_forms.rb", "test/test_if_modified_since.rb", "test/test_keep_alive.rb", "test/test_links.rb", "test/test_mech.rb", "test/test_mechanize_file.rb", "test/test_multi_select.rb", "test/test_no_attributes.rb", "test/test_option.rb", "test/test_page.rb", "test/test_pluggable_parser.rb", "test/test_post_form.rb", "test/test_pretty_print.rb", "test/test_radiobutton.rb", "test/test_redirect_limit_reached.rb", "test/test_referer.rb", "test/test_relative_links.rb", "test/test_response_code.rb", "test/test_save_file.rb", "test/test_select.rb", "test/test_select_all.rb", "test/test_select_none.rb", "test/test_select_noopts.rb", "test/test_set_fields.rb", "test/test_ssl_server.rb", "test/test_subclass.rb", "test/test_textarea.rb", "test/test_upload.rb"]
19
+ s.test_files = ["test/chain/test_argument_validator.rb", "test/chain/test_custom_headers.rb", "test/chain/test_parameter_resolver.rb", "test/chain/test_request_resolver.rb", "test/chain/test_response_reader.rb", "test/test_authenticate.rb", "test/test_bad_links.rb", "test/test_blank_form.rb", "test/test_checkboxes.rb", "test/test_content_type.rb", "test/test_cookie_class.rb", "test/test_cookie_jar.rb", "test/test_cookies.rb", "test/test_encoded_links.rb", "test/test_errors.rb", "test/test_follow_meta.rb", "test/test_form_action.rb", "test/test_form_as_hash.rb", "test/test_form_button.rb", "test/test_form_no_inputname.rb", "test/test_forms.rb", "test/test_frames.rb", "test/test_get_headers.rb", "test/test_gzipping.rb", "test/test_hash_api.rb", "test/test_history.rb", "test/test_history_added.rb", "test/test_html_unscape_forms.rb", "test/test_if_modified_since.rb", "test/test_keep_alive.rb", "test/test_links.rb", "test/test_mech.rb", "test/test_mechanize_file.rb", "test/test_multi_select.rb", "test/test_no_attributes.rb", "test/test_option.rb", "test/test_page.rb", "test/test_pluggable_parser.rb", "test/test_post_form.rb", "test/test_pretty_print.rb", "test/test_radiobutton.rb", "test/test_redirect_limit_reached.rb", "test/test_referer.rb", "test/test_relative_links.rb", "test/test_response_code.rb", "test/test_save_file.rb", "test/test_scheme.rb", "test/test_select.rb", "test/test_select_all.rb", "test/test_select_none.rb", "test/test_select_noopts.rb", "test/test_set_fields.rb", "test/test_ssl_server.rb", "test/test_subclass.rb", "test/test_textarea.rb", "test/test_upload.rb", "test/test_verbs.rb"]
20
20
 
21
21
  if s.respond_to? :specification_version then
22
22
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION