kitamomonga-mechanize 0.9.3.20090724215219

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 (177) hide show
  1. data/CHANGELOG.rdoc +504 -0
  2. data/EXAMPLES.rdoc +171 -0
  3. data/FAQ.rdoc +11 -0
  4. data/GUIDE.rdoc +122 -0
  5. data/LICENSE.rdoc +340 -0
  6. data/Manifest.txt +176 -0
  7. data/README.rdoc +60 -0
  8. data/Rakefile +33 -0
  9. data/examples/flickr_upload.rb +23 -0
  10. data/examples/mech-dump.rb +7 -0
  11. data/examples/proxy_req.rb +9 -0
  12. data/examples/rubyforge.rb +21 -0
  13. data/examples/spider.rb +11 -0
  14. data/lib/mechanize.rb +666 -0
  15. data/lib/mechanize/chain.rb +34 -0
  16. data/lib/mechanize/chain/auth_headers.rb +78 -0
  17. data/lib/mechanize/chain/body_decoding_handler.rb +46 -0
  18. data/lib/mechanize/chain/connection_resolver.rb +76 -0
  19. data/lib/mechanize/chain/custom_headers.rb +21 -0
  20. data/lib/mechanize/chain/handler.rb +9 -0
  21. data/lib/mechanize/chain/header_resolver.rb +51 -0
  22. data/lib/mechanize/chain/parameter_resolver.rb +22 -0
  23. data/lib/mechanize/chain/post_connect_hook.rb +0 -0
  24. data/lib/mechanize/chain/post_page_hook.rb +18 -0
  25. data/lib/mechanize/chain/pre_connect_hook.rb +20 -0
  26. data/lib/mechanize/chain/request_resolver.rb +30 -0
  27. data/lib/mechanize/chain/response_body_parser.rb +38 -0
  28. data/lib/mechanize/chain/response_header_handler.rb +48 -0
  29. data/lib/mechanize/chain/response_reader.rb +39 -0
  30. data/lib/mechanize/chain/ssl_resolver.rb +40 -0
  31. data/lib/mechanize/chain/uri_resolver.rb +75 -0
  32. data/lib/mechanize/content_type_error.rb +14 -0
  33. data/lib/mechanize/cookie.rb +70 -0
  34. data/lib/mechanize/cookie_jar.rb +188 -0
  35. data/lib/mechanize/file.rb +71 -0
  36. data/lib/mechanize/file_response.rb +60 -0
  37. data/lib/mechanize/file_saver.rb +37 -0
  38. data/lib/mechanize/form.rb +364 -0
  39. data/lib/mechanize/form/button.rb +7 -0
  40. data/lib/mechanize/form/check_box.rb +11 -0
  41. data/lib/mechanize/form/field.rb +26 -0
  42. data/lib/mechanize/form/file_upload.rb +22 -0
  43. data/lib/mechanize/form/image_button.rb +21 -0
  44. data/lib/mechanize/form/multi_select_list.rb +67 -0
  45. data/lib/mechanize/form/option.rb +49 -0
  46. data/lib/mechanize/form/radio_button.rb +36 -0
  47. data/lib/mechanize/form/select_list.rb +43 -0
  48. data/lib/mechanize/headers.rb +11 -0
  49. data/lib/mechanize/history.rb +65 -0
  50. data/lib/mechanize/inspect.rb +88 -0
  51. data/lib/mechanize/monkey_patch.rb +35 -0
  52. data/lib/mechanize/page.rb +279 -0
  53. data/lib/mechanize/page/base.rb +8 -0
  54. data/lib/mechanize/page/encoding.rb +61 -0
  55. data/lib/mechanize/page/frame.rb +20 -0
  56. data/lib/mechanize/page/link.rb +53 -0
  57. data/lib/mechanize/page/meta.rb +50 -0
  58. data/lib/mechanize/pluggable_parsers.rb +101 -0
  59. data/lib/mechanize/redirect_limit_reached_error.rb +16 -0
  60. data/lib/mechanize/redirect_not_get_or_head_error.rb +18 -0
  61. data/lib/mechanize/response_code_error.rb +22 -0
  62. data/lib/mechanize/unsupported_scheme_error.rb +8 -0
  63. data/lib/mechanize/util.rb +73 -0
  64. data/test/chain/test_argument_validator.rb +14 -0
  65. data/test/chain/test_auth_headers.rb +25 -0
  66. data/test/chain/test_custom_headers.rb +18 -0
  67. data/test/chain/test_header_resolver.rb +28 -0
  68. data/test/chain/test_parameter_resolver.rb +35 -0
  69. data/test/chain/test_request_resolver.rb +29 -0
  70. data/test/chain/test_response_reader.rb +24 -0
  71. data/test/data/htpasswd +1 -0
  72. data/test/data/server.crt +16 -0
  73. data/test/data/server.csr +12 -0
  74. data/test/data/server.key +15 -0
  75. data/test/data/server.pem +15 -0
  76. data/test/helper.rb +129 -0
  77. data/test/htdocs/alt_text.html +10 -0
  78. data/test/htdocs/bad_form_test.html +9 -0
  79. data/test/htdocs/button.jpg +0 -0
  80. data/test/htdocs/empty_form.html +6 -0
  81. data/test/htdocs/file_upload.html +26 -0
  82. data/test/htdocs/find_link.html +41 -0
  83. data/test/htdocs/form_multi_select.html +16 -0
  84. data/test/htdocs/form_multival.html +37 -0
  85. data/test/htdocs/form_no_action.html +18 -0
  86. data/test/htdocs/form_no_input_name.html +16 -0
  87. data/test/htdocs/form_select.html +16 -0
  88. data/test/htdocs/form_select_all.html +16 -0
  89. data/test/htdocs/form_select_none.html +17 -0
  90. data/test/htdocs/form_select_noopts.html +10 -0
  91. data/test/htdocs/form_set_fields.html +14 -0
  92. data/test/htdocs/form_test.html +188 -0
  93. data/test/htdocs/frame_test.html +30 -0
  94. data/test/htdocs/google.html +13 -0
  95. data/test/htdocs/iframe_test.html +16 -0
  96. data/test/htdocs/index.html +6 -0
  97. data/test/htdocs/link with space.html +5 -0
  98. data/test/htdocs/meta_cookie.html +11 -0
  99. data/test/htdocs/no_title_test.html +6 -0
  100. data/test/htdocs/relative/tc_relative_links.html +21 -0
  101. data/test/htdocs/tc_bad_charset.html +9 -0
  102. data/test/htdocs/tc_bad_links.html +5 -0
  103. data/test/htdocs/tc_base_link.html +8 -0
  104. data/test/htdocs/tc_blank_form.html +11 -0
  105. data/test/htdocs/tc_charset.html +6 -0
  106. data/test/htdocs/tc_checkboxes.html +19 -0
  107. data/test/htdocs/tc_encoded_links.html +5 -0
  108. data/test/htdocs/tc_follow_meta.html +8 -0
  109. data/test/htdocs/tc_form_action.html +48 -0
  110. data/test/htdocs/tc_links.html +19 -0
  111. data/test/htdocs/tc_no_attributes.html +16 -0
  112. data/test/htdocs/tc_pretty_print.html +17 -0
  113. data/test/htdocs/tc_radiobuttons.html +17 -0
  114. data/test/htdocs/tc_referer.html +10 -0
  115. data/test/htdocs/tc_relative_links.html +19 -0
  116. data/test/htdocs/tc_textarea.html +23 -0
  117. data/test/htdocs/test_bad_encoding.html +52 -0
  118. data/test/htdocs/unusual______.html +5 -0
  119. data/test/servlets.rb +365 -0
  120. data/test/ssl_server.rb +48 -0
  121. data/test/test_authenticate.rb +71 -0
  122. data/test/test_bad_links.rb +25 -0
  123. data/test/test_blank_form.rb +16 -0
  124. data/test/test_checkboxes.rb +61 -0
  125. data/test/test_content_type.rb +13 -0
  126. data/test/test_cookie_class.rb +338 -0
  127. data/test/test_cookie_jar.rb +362 -0
  128. data/test/test_cookies.rb +123 -0
  129. data/test/test_encoded_links.rb +20 -0
  130. data/test/test_errors.rb +49 -0
  131. data/test/test_follow_meta.rb +108 -0
  132. data/test/test_form_action.rb +52 -0
  133. data/test/test_form_as_hash.rb +61 -0
  134. data/test/test_form_button.rb +38 -0
  135. data/test/test_form_no_inputname.rb +15 -0
  136. data/test/test_forms.rb +577 -0
  137. data/test/test_frames.rb +25 -0
  138. data/test/test_get_headers.rb +73 -0
  139. data/test/test_gzipping.rb +22 -0
  140. data/test/test_hash_api.rb +45 -0
  141. data/test/test_history.rb +142 -0
  142. data/test/test_history_added.rb +16 -0
  143. data/test/test_html_unscape_forms.rb +39 -0
  144. data/test/test_if_modified_since.rb +20 -0
  145. data/test/test_keep_alive.rb +31 -0
  146. data/test/test_links.rb +127 -0
  147. data/test/test_mech.rb +289 -0
  148. data/test/test_mechanize_file.rb +72 -0
  149. data/test/test_meta.rb +65 -0
  150. data/test/test_multi_select.rb +106 -0
  151. data/test/test_no_attributes.rb +13 -0
  152. data/test/test_option.rb +18 -0
  153. data/test/test_page.rb +127 -0
  154. data/test/test_page_encoding.rb +298 -0
  155. data/test/test_pluggable_parser.rb +145 -0
  156. data/test/test_post_form.rb +34 -0
  157. data/test/test_pretty_print.rb +22 -0
  158. data/test/test_radiobutton.rb +75 -0
  159. data/test/test_redirect_limit_reached.rb +39 -0
  160. data/test/test_redirect_verb_handling.rb +43 -0
  161. data/test/test_referer.rb +39 -0
  162. data/test/test_relative_links.rb +40 -0
  163. data/test/test_request.rb +13 -0
  164. data/test/test_response_code.rb +52 -0
  165. data/test/test_save_file.rb +103 -0
  166. data/test/test_scheme.rb +63 -0
  167. data/test/test_select.rb +106 -0
  168. data/test/test_select_all.rb +15 -0
  169. data/test/test_select_none.rb +15 -0
  170. data/test/test_select_noopts.rb +16 -0
  171. data/test/test_set_fields.rb +44 -0
  172. data/test/test_ssl_server.rb +20 -0
  173. data/test/test_subclass.rb +14 -0
  174. data/test/test_textarea.rb +45 -0
  175. data/test/test_upload.rb +109 -0
  176. data/test/test_verbs.rb +25 -0
  177. metadata +320 -0
@@ -0,0 +1,50 @@
1
+ class Mechanize
2
+ class Page < Mechanize::File
3
+ # This class encapsulates a Meta tag. Mechanize treats meta tags just
4
+ # like 'a' tags. Meta objects will contain links, but most likely will
5
+ # have no text.
6
+ class Meta < Link
7
+
8
+ # Matches the content attribute of a meta tag. After the match:
9
+ #
10
+ # $1:: delay
11
+ # $3:: url
12
+ #
13
+ CONTENT_REGEXP = /^\s*(\d+\.?\d*)(;|;\s*url=\s*['"]?(\S*?)['"]?)?\s*$/i
14
+
15
+ class << self
16
+ # Parses the delay and url from the content attribute of a meta tag.
17
+ # Parse requires the uri of the current page to infer a url when no
18
+ # url is specified. If a block is given, the parsed delay and url
19
+ # will be passed to it for further processing.
20
+ #
21
+ # Returns nil if the delay and url cannot be parsed.
22
+ #
23
+ # # <meta http-equiv="refresh" content="5;url=http://example.com/" />
24
+ # uri = URI.parse('http://current.com/')
25
+ #
26
+ # Meta.parse("5;url=http://example.com/", uri) # => ['5', 'http://example.com/']
27
+ # Meta.parse("5;url=", uri) # => ['5', 'http://current.com/']
28
+ # Meta.parse("5", uri) # => ['5', 'http://current.com/']
29
+ # Meta.parse("invalid content", uri) # => nil
30
+ #
31
+ def parse(content, uri)
32
+ if content && content =~ CONTENT_REGEXP
33
+ delay, url = $1, $3
34
+
35
+ url = case url
36
+ when nil, "" then uri.to_s
37
+ when /^http/i then url
38
+ else "http://#{uri.host}#{url}"
39
+ end
40
+
41
+ block_given? ? yield(delay, url) : [delay, url]
42
+ else
43
+ nil
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+
@@ -0,0 +1,101 @@
1
+ require 'mechanize/file'
2
+ require 'mechanize/file_saver'
3
+ require 'mechanize/page'
4
+
5
+ class Mechanize
6
+ # = Synopsis
7
+ # This class is used to register and maintain pluggable parsers for
8
+ # Mechanize to use.
9
+ #
10
+ # A Pluggable Parser is a parser that Mechanize uses for any particular
11
+ # content type. Mechanize will ask PluggableParser for the class it
12
+ # should initialize given any content type. This class allows users to
13
+ # register their own pluggable parsers, or modify existing pluggable
14
+ # parsers.
15
+ #
16
+ # PluggableParser returns a Mechanize::File object for content types
17
+ # that it does not know how to handle. Mechanize::File provides
18
+ # basic functionality for any content type, so it is a good class to
19
+ # extend when building your own parsers.
20
+ # == Example
21
+ # To create your own parser, just create a class that takes four
22
+ # parameters in the constructor. Here is an example of registering
23
+ # a pluggable parser that handles CSV files:
24
+ # class CSVParser < Mechanize::File
25
+ # attr_reader :csv
26
+ # def initialize(uri=nil, response=nil, body=nil, code=nil)
27
+ # super(uri, response, body, code)
28
+ # @csv = CSV.parse(body)
29
+ # end
30
+ # end
31
+ # agent = Mechanize.new
32
+ # agent.pluggable_parser.csv = CSVParser
33
+ # agent.get('http://example.com/test.csv') # => CSVParser
34
+ # Now any page that returns the content type of 'text/csv' will initialize
35
+ # a CSVParser and return that object to the caller.
36
+ #
37
+ # To register a pluggable parser for a content type that pluggable parser
38
+ # does not know about, just use the hash syntax:
39
+ # agent.pluggable_parser['text/something'] = SomeClass
40
+ #
41
+ # To set the default parser, just use the 'defaut' method:
42
+ # agent.pluggable_parser.default = SomeClass
43
+ # Now all unknown content types will be instances of SomeClass.
44
+ class PluggableParser
45
+ CONTENT_TYPES = {
46
+ :html => 'text/html',
47
+ :wap => 'application/vnd.wap.xhtml+xml',
48
+ :xhtml => 'application/xhtml+xml',
49
+ :pdf => 'application/pdf',
50
+ :csv => 'text/csv',
51
+ :xml => 'text/xml',
52
+ }
53
+
54
+ attr_accessor :default
55
+
56
+ def initialize
57
+ @parsers = { CONTENT_TYPES[:html] => Page,
58
+ CONTENT_TYPES[:xhtml] => Page,
59
+ CONTENT_TYPES[:wap] => Page,
60
+ }
61
+ @default = File
62
+ end
63
+
64
+ def parser(content_type)
65
+ content_type.nil? ? default : @parsers[content_type] || default
66
+ end
67
+
68
+ def register_parser(content_type, klass)
69
+ @parsers[content_type] = klass
70
+ end
71
+
72
+ def html=(klass)
73
+ register_parser(CONTENT_TYPES[:html], klass)
74
+ register_parser(CONTENT_TYPES[:xhtml], klass)
75
+ end
76
+
77
+ def xhtml=(klass)
78
+ register_parser(CONTENT_TYPES[:xhtml], klass)
79
+ end
80
+
81
+ def pdf=(klass)
82
+ register_parser(CONTENT_TYPES[:pdf], klass)
83
+ end
84
+
85
+ def csv=(klass)
86
+ register_parser(CONTENT_TYPES[:csv], klass)
87
+ end
88
+
89
+ def xml=(klass)
90
+ register_parser(CONTENT_TYPES[:xml], klass)
91
+ end
92
+
93
+ def [](content_type)
94
+ @parsers[content_type]
95
+ end
96
+
97
+ def []=(content_type, klass)
98
+ @parsers[content_type] = klass
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,16 @@
1
+ class Mechanize
2
+ # Thrown when too many redirects are sent
3
+ class RedirectLimitReachedError < RuntimeError
4
+ attr_reader :page, :response_code, :redirects
5
+ def initialize(page, redirects)
6
+ @page = page
7
+ @redirects = redirects
8
+ @response_code = page.code
9
+ end
10
+
11
+ def to_s
12
+ "Maximum redirect limit (#{redirects}) reached"
13
+ end
14
+ alias :inspect :to_s
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ class Mechanize
2
+ # Thrown when a POST, PUT, or DELETE request results in a redirect
3
+ # see RFC 2616 10.3.2, 10.3.3 http://www.ietf.org/rfc/rfc2616.txt
4
+ class RedirectNotGetOrHeadError < RuntimeError
5
+ attr_reader :page, :response_code, :verb, :uri
6
+ def initialize(page, verb)
7
+ @page = page
8
+ @verb = verb
9
+ @uri = page.uri
10
+ @response_code = page.code
11
+ end
12
+
13
+ def to_s
14
+ "#{@response_code} redirect received after a #{@verb} request"
15
+ end
16
+ alias :inspect :to_s
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ class Mechanize
2
+ # =Synopsis
3
+ # This error is thrown when Mechanize encounters a response code it does
4
+ # not know how to handle. Currently, this exception will be thrown
5
+ # if Mechanize encounters response codes other than 200, 301, or 302.
6
+ # Any other response code is up to the user to handle.
7
+ class ResponseCodeError < RuntimeError
8
+ attr_reader :response_code
9
+ attr_reader :page
10
+
11
+ def initialize(page)
12
+ @page = page
13
+ @response_code = page.code
14
+ end
15
+
16
+ def to_s
17
+ "#{response_code} => #{Net::HTTPResponse::CODE_TO_OBJ[response_code]}"
18
+ end
19
+
20
+ def inspect; to_s; end
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ class Mechanize
2
+ class UnsupportedSchemeError < RuntimeError
3
+ attr_accessor :scheme
4
+ def initialize(scheme)
5
+ @scheme = scheme
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,73 @@
1
+ require 'cgi'
2
+
3
+ class Mechanize
4
+ class Util
5
+ CODE_DIC = {
6
+ :JIS => "ISO-2022-JP",
7
+ :EUC => "EUC-JP",
8
+ :SJIS => "SHIFT_JIS",
9
+ :UTF8 => "UTF-8", :UTF16 => "UTF-16", :UTF32 => "UTF-32"}
10
+
11
+ NKF_TO_ICONV = {
12
+ 'ASCII-8BIT' => 'CP1252',
13
+ 'SHIFT_JIS' => 'CP932',
14
+ }
15
+
16
+ class << self
17
+ def build_query_string(parameters, enc=nil)
18
+ parameters.map { |k,v|
19
+ # WEBrick::HTTP.escape* has some problems about m17n on ruby-1.9.*.
20
+ [CGI.escape(k.to_s), CGI.escape(v.to_s)].join("=") if k
21
+ }.compact.join('&')
22
+ end
23
+
24
+ def to_native_charset(s, code=nil)
25
+ if Mechanize.html_parser == Nokogiri::HTML
26
+ return unless s
27
+ code ||= detect_charset(s)
28
+ Iconv.iconv("UTF-8", code, s).join("")
29
+ else
30
+ s
31
+ end
32
+ end
33
+
34
+ def from_native_charset(s, code)
35
+ if Mechanize.html_parser == Nokogiri::HTML
36
+ return unless s
37
+ Iconv.iconv(code, "UTF-8", s).join("")
38
+ else
39
+ return s
40
+ end
41
+ end
42
+
43
+ def html_unescape(s)
44
+ return s unless s
45
+ s.gsub(/&(\w+|#[0-9]+);/) { |match|
46
+ number = case match
47
+ when /&(\w+);/
48
+ Mechanize.html_parser::NamedCharacters[$1]
49
+ when /&#([0-9]+);/
50
+ $1.to_i
51
+ end
52
+
53
+ number ? ([number].pack('U') rescue match) : match
54
+ }
55
+ end
56
+
57
+ def detect_charset(src)
58
+ tmp = NKF.guess(src || "<html></html>")
59
+ if RUBY_VERSION >= "1.9.0"
60
+ enc = tmp.to_s.upcase
61
+ else
62
+ enc = NKF.constants.find{|c|
63
+ NKF.const_get(c) == tmp
64
+ }
65
+ enc = CODE_DIC[enc.intern]
66
+ end
67
+ enc = NKF_TO_ICONV[enc] if NKF_TO_ICONV[enc]
68
+ enc || "CP1252"
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,14 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
2
+
3
+ class TestURIResolver < Test::Unit::TestCase
4
+ def test_handle
5
+ v = Mechanize::Chain.new([
6
+ Mechanize::Chain::URIResolver.new(Hash.new { |h,k|
7
+ h[k] = lambda { |u,r| u }
8
+ })
9
+ ])
10
+ assert_raises(ArgumentError) { v.handle({}) }
11
+ assert_nothing_raised { v.handle({:uri => 'http://google.com/'}) }
12
+ assert_raises(RuntimeError) { v.handle({:uri => 'google'}) }
13
+ end
14
+ end
@@ -0,0 +1,25 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
2
+
3
+ class TestAuthHeaders < Test::Unit::TestCase
4
+ def test_auth
5
+ url = URI.parse('http://www.anthonychaves.net/tests.xml')
6
+ digest = %Q!Digest realm="www.anthonychaves.net", qop="auth", algorithm=MD5, nonce="MTI0NTEyMTYyNjo0ZTY2MjhlZWMyZmM1ZjA0M2Y1Njc1MGU0YTA2MWY5OQ==", opaque="9f455d4e71e8d46a6d3aaef8bf8b0d9e"!
7
+ v = Mechanize::Chain.new([
8
+ Mechanize::Chain::AuthHeaders.new({(url.host) => :digest}, "anthony", "password", digest)
9
+ ])
10
+
11
+ hash = {
12
+ :request => Net::HTTP::Get.new(url.request_uri),
13
+ :uri => url
14
+ }
15
+ v.handle(hash)
16
+ actual_authorization = hash[:request]['Authorization']
17
+ # The chain gave our request an Authorization header with client-generated values and derivatives.
18
+ # They should be scrubbed before comparing to the expected result because they change
19
+ # on each invokation
20
+ actual_authorization.gsub!(/cnonce=\"\w+?\"/, "cnonce=\"scrubbed_cnonce\"").gsub!(/response=\"\w+?\"/, "response=\"scrubbed_response\"")
21
+
22
+ expected_authorization = %Q!Digest username="anthony", qop=auth, uri="/tests.xml", algorithm="MD5", opaque="9f455d4e71e8d46a6d3aaef8bf8b0d9e", nonce="MTI0NTEyMTYyNjo0ZTY2MjhlZWMyZmM1ZjA0M2Y1Njc1MGU0YTA2MWY5OQ==", realm="www.anthonychaves.net", nc=00000001, cnonce="scrubbed_cnonce", response="scrubbed_response"!
23
+ assert_equal(expected_authorization, actual_authorization)
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
2
+
3
+ class TestCustomHeaders < Test::Unit::TestCase
4
+ def test_handle
5
+ v = Mechanize::Chain.new([
6
+ Mechanize::Chain::CustomHeaders.new
7
+ ])
8
+ url = URI.parse('http://tenderlovemaking.com/')
9
+ hash = {
10
+ :request => Net::HTTP::Get.new(url.request_uri),
11
+ :headers => { 'Content-Length' => 300 }
12
+ }
13
+ v.handle(hash)
14
+ headers = hash[:request].to_hash
15
+ assert(headers.key?('content-length'))
16
+ assert_equal([300], headers['content-length'])
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
2
+
3
+ class TestHeaderResolver < Test::Unit::TestCase
4
+ def setup
5
+ @chain = Mechanize::Chain.new([
6
+ Mechanize::Chain::HeaderResolver.new(
7
+ true,
8
+ 300,
9
+ Mechanize::CookieJar.new,
10
+ 'foobar',
11
+ {
12
+ 'hello' => 'world',
13
+ 'Content-Type' => 'utf-8'
14
+ }
15
+ )
16
+ ])
17
+ end
18
+
19
+ def test_handle
20
+ hash = {
21
+ :request => {},
22
+ :uri => URI.parse('http://google.com/')
23
+ }
24
+ @chain.handle(hash)
25
+ assert_equal 'world', hash[:request]['hello']
26
+ assert_equal 'utf-8', hash[:request]['Content-Type']
27
+ end
28
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
2
+
3
+ class TestParameterResolver < Test::Unit::TestCase
4
+ def test_handle_get
5
+ v = Mechanize::Chain.new([
6
+ Mechanize::Chain::ParameterResolver.new
7
+ ])
8
+ hash = {
9
+ :uri => URI.parse('http://google.com/'),
10
+ :params => { :q => 'hello' },
11
+ :verb => :get
12
+ }
13
+ assert_nothing_raised {
14
+ v.handle(hash)
15
+ }
16
+ assert_equal('q=hello', hash[:uri].query)
17
+ assert_equal([], hash[:params])
18
+ end
19
+
20
+ def test_handle_post
21
+ v = Mechanize::Chain.new([
22
+ Mechanize::Chain::ParameterResolver.new
23
+ ])
24
+ hash = {
25
+ :uri => URI.parse('http://google.com/'),
26
+ :params => { :q => 'hello' },
27
+ :verb => :post
28
+ }
29
+ assert_nothing_raised {
30
+ v.handle(hash)
31
+ }
32
+ assert_equal('', hash[:uri].query.to_s)
33
+ assert_equal({ :q => 'hello' }, hash[:params])
34
+ end
35
+ end
@@ -0,0 +1,29 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
2
+
3
+ class TestRequestResolver < Test::Unit::TestCase
4
+ def test_handle_get
5
+ v = Mechanize::Chain.new([
6
+ Mechanize::Chain::RequestResolver.new
7
+ ])
8
+ hash = {
9
+ :uri => URI.parse('http://google.com'),
10
+ :verb => :get
11
+ }
12
+ assert_nothing_raised { v.handle(hash) }
13
+ assert_kind_of(Net::HTTP::Get, hash[:request])
14
+ assert_equal('/', hash[:request].path)
15
+ end
16
+
17
+ def test_handle_post
18
+ v = Mechanize::Chain.new([
19
+ Mechanize::Chain::RequestResolver.new
20
+ ])
21
+ hash = {
22
+ :uri => URI.parse('http://google.com'),
23
+ :verb => :post
24
+ }
25
+ assert_nothing_raised { v.handle(hash) }
26
+ assert_kind_of(Net::HTTP::Post, hash[:request])
27
+ assert_equal('/', hash[:request].path)
28
+ end
29
+ end