WWW::Mechanize on Nokogiri
Hpricot互換ということで思いつく。
が、やってみたらテストが結構な結果に。
242 tests, 1239 assertions, 20 failures, 4 errors
ひょっとしてMechanizeってインタフェース越しだけじゃなく
Hpricotの中身にも手を出してる?
ちなみにwww/mechanize/nokogiri.rb全文。
# prevent to load real hpricot library $LOADED_FEATURES.push 'hpricot.rb' module WWW class Mechanize Hpricot = nil end end require 'nokogiri' require 'www/mechanize' WWW::Mechanize.html_parser = Nokogiri
でもってテスト出力。
$ rake test (in C:/home/ruby/mechanize-nokogiri) Loaded suite C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake/rake_test_loader Started ......................................F..FFFFF..FFFF.F...F..............................................................................EEEE......F........F.........................................................................FFF.FFF...... Finished in 2.562 seconds. 1) Failure: test_delete_field(FormsMechTest) [./test/test_forms.rb:502]: <2> expected but was <4>. 2) Failure: test_fields_as_accessors(FormsMechTest) [./test/test_forms.rb:478]: <2> expected but was <4>. 3) Failure: test_get(FormsMechTest) [./test/test_forms.rb:189]: <1> expected but was <8>. 4) Failure: test_get_multival(FormsMechTest) [./test/test_forms.rb:60]: <2> expected but was <4>. 5) Failure: test_get_with_param_in_action(FormsMechTest) [./test/test_forms.rb:420]: <1> expected but was <8>. 6) Failure: test_get_with_space_in_action(FormsMechTest) [./test/test_forms.rb:316]: <1> expected but was <8>. 7) Failure: test_post(FormsMechTest) [./test/test_forms.rb:81]: <3> expected but was <8>. 8) Failure: test_post_multival(FormsMechTest) [./test/test_forms.rb:20]: <2> expected but was <4>. 9) Failure: test_post_with_param_in_action(FormsMechTest) [./test/test_forms.rb:368]: <1> expected but was <8>. 10) Failure: test_post_with_space_in_action(FormsMechTest) [./test/test_forms.rb:264]: <1> expected but was <8>. 11) Failure: test_submit_on_form(FormsMechTest) [./test/test_forms.rb:40]: <2> expected but was <4>. 12) Failure: test_alt_text(LinksMechTest) [./test/test_links.rb:49]: <""> expected but was <"alt text">. 13) Error: test_field(TestCheckBoxes): NameError: uninitialized constant Nokogiri::NamedCharacters C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/util.rb:18:in `html_unescape' C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/util.rb:15:in `gsub' C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/util.rb:15:in `html_unescape' C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/form/field.rb:14:in `initialize' ./test/test_html_unscape_forms.rb:5:in `new' ./test/test_html_unscape_forms.rb:5:in `test_field' 14) Error: test_file_upload(TestCheckBoxes): NameError: uninitialized constant Nokogiri::NamedCharacters C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/util.rb:18:in `html_unescape' C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/util.rb:15:in `gsub' C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/util.rb:15:in `html_unescape' C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/form/file_upload.rb:17:in `initialize' ./test/test_html_unscape_forms.rb:19:in `new' ./test/test_html_unscape_forms.rb:19:in `test_file_upload' 15) Error: test_image_button(TestCheckBoxes): NameError: uninitialized constant Nokogiri::NamedCharacters C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/util.rb:18:in `html_unescape' C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/util.rb:15:in `gsub' C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/util.rb:15:in `html_unescape' C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/form/field.rb:14:in `initialize' C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/form/image_button.rb:12:in `initialize' ./test/test_html_unscape_forms.rb:29:in `new' ./test/test_html_unscape_forms.rb:29:in `test_image_button' 16) Error: test_radio_button(TestCheckBoxes): NameError: uninitialized constant Nokogiri::NamedCharacters C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/util.rb:18:in `html_unescape' C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/util.rb:15:in `gsub' C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/util.rb:15:in `html_unescape' C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/form/field.rb:14:in `initialize' C:/ruby/ruby1.8/lib/ruby/gems/1.8/gems/mechanize-0.8.4/lib/www/mechanize/form/radio_button.rb:12:in `initialize' ./test/test_html_unscape_forms.rb:35:in `new' ./test/test_html_unscape_forms.rb:35:in `test_radio_button' 17) Failure: test_get_encoded_action(TestFormAction) [./test/test_form_action.rb:24]: <"http://localhost/form_post?first_name=Aaron"> expected but was <"http://localhost/form_post?first_name=Aaron&first_name=&first_name=&first_name=">. 18) Failure: test_fields_as_hash(TestFormHash) [./test/test_form_as_hash.rb:37]: <2> expected but was <4>. 19) Failure: test_empty_text_area(TestTextArea) [./test/test_textarea.rb:15]: <1> expected but was <4>. 20) Failure: test_multi_textfield(TestTextArea) [./test/test_textarea.rb:29]: <2> expected but was <4>. 21) Failure: test_non_empty_textfield(TestTextArea) [./test/test_textarea.rb:21]: <"sample text"> expected but was <"">. 22) Failure: test_form_io_obj(UploadMechTest) [./test/test_upload.rb:87]: <"--WRQmAocqzJPkIXQaVCBh\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\n\r\n--WRQmAocqzJPkIXQaVCBh\r\nContent-Disposition: form-data; name=\"foo[aaron]\"\r\n\r\ntest\r\n--WRQmAocqzJPkIXQaVCBh\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\n\r\n--WRQmAocqzJPkIXQaVCBh\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\n\r\n--WRQmAocqzJPkIXQaVCBh\r\nContent-Disposition: form-data; name=\"userfile1\"; filename=\"helper.rb\"\r\nContent-Transfer-Encoding: binary\r\n\r\nrequire 'test/unit'\nrequire 'rubygems'\nrequire 'www/mechanize/nokogiri'\nrequire 'webrick/httputils'\nrequire File.join(File.dirname(__FILE__),'servlets')\n\nBASE_DIR = File.dirname(__FILE__)\n\n# Move this to a test base class\nmodule MechTestHelper\n def self.fake_page(agent)\n html = <<-END\n <html><body>\n <form><input type=\"submit\" value=\"submit\" /></form>\n </body></html>\n END\n html_response = { 'content-type' => 'text/html' }\n page = WWW::Mechanize::Page.new( nil, html_response, html, 200, agent )\n end\nend\n\nclass Net::HTTP\n alias :old_do_start :do_start\n\n def do_start\n @started = true\n end\n\n SERVLETS = {\n '/gzip' => GzipServlet,\n '/form_post' => FormTest,\n '/basic_auth' => BasicAuthServlet,\n '/form post' => FormTest,\n '/response_code' => ResponseCodeTest,\n '/bad_content_type' => BadContentTypeTest,\n '/content_type_test' => ContentTypeTest,\n '/referer' => RefererServlet,\n '/file_upload' => FileUploadTest,\n '/one_cookie' => OneCookieTest,\n '/one_cookie_no_space' => OneCookieNoSpacesTest,\n '/many_cookies' => ManyCookiesTest,\n '/many_cookies_as_string' => ManyCookiesAsStringTest,\n '/send_cookies' => SendCookiesTest,\n '/if_modified_since' => ModifiedSinceServlet,\n '/http_headers' => HeaderServlet,\n '/infinite_redirect' => InfiniteRedirectTest,\n '/digest_auth' => DigestAuthServlet,\n '/verb' => VerbServlet,\n }\n\n PAGE_CACHE = {}\n\n alias :old_request :request\n\n def request(request, *data, &block)\n url = URI.parse(request.path)\n path = URI.unescape(url.path)\n\n path = '/index.html' if path == '/'\n\n res = Response.new\n request.query = WEBrick::HTTPUtils.parse_query(url.query)\n request.cookies = WEBrick::Cookie.parse(request['Cookie'])\n if SERVLETS[path]\n if request.method == \"POST\"\n if request['Content-Type'] =~ /^multipart\\/form-data/\n request.body = data.first\n else\n request.query = WEBrick::HTTPUtils.parse_query(data.first)\n end\n end\n SERVLETS[path].new({}).send(\"do_\#{request.method}\", request, res)\n else\n filename = \"htdocs\#{path.gsub(/[^\\/\\\\.\\w_\\s]/, '_')}\"\n unless PAGE_CACHE[filename]\n File.open(\"\#{BASE_DIR}/\#{filename}\", 'rb') { |file|\n PAGE_CACHE[filename] = file.read\n }\n end\n res.body = PAGE_CACHE[filename]\n end\n\n res['Content-Type'] ||= 'text/html'\n res['Content-Length'] ||= res.body.length.to_s\n res.code ||= \"200\"\n\n res.cookies.each do |cookie|\n res.add_field('Set-Cookie', cookie.to_s)\n end\n yield res if block_given?\n res\n end\nend\n\nclass Net::HTTPRequest\n attr_accessor :query, :body, :cookies, :user\nend\n\nclass Response\n include Net::HTTPHeader\n\n attr_reader :code\n attr_accessor :body, :query, :cookies\n \n def code=(c)\n @code = c.to_s\n end\n\n alias :status :code\n alias :status= :code=\n\n def initialize\n @header = {}\n @body = ''\n @code = nil\n @query = nil\n @cookies = []\n end\n\n def read_body\n yield body\n end\nend\n\r\n--WRQmAocqzJPkIXQaVCBh\r\nContent-Disposition: form-data; name=\"green[eggs]\"; filename=\"\"\r\nContent-Transfer-Encoding: binary\r\n\r\n\r\n--WRQmAocqzJPkIXQaVCBh\r\nContent-Disposition: form-data; name=\"green[eggs]\"; filename=\"\"\r\nContent-Transfer-Encoding: binary\r\n\r\n\r\n--WRQmAocqzJPkIXQaVCBh--\r\n"> expected to be =~ </Content\-Disposition:\ form\-data;\ name="green\[eggs\]";\ filename="helper\.rb"/>. 23) Failure: test_form_multipart(UploadMechTest) [./test/test_upload.rb:55]: <"--LTFyFRWteRldRjRmKicS\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\n\r\n--LTFyFRWteRldRjRmKicS\r\nContent-Disposition: form-data; name=\"foo[aaron]\"\r\n\r\ntest\r\n--LTFyFRWteRldRjRmKicS\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\n\r\n--LTFyFRWteRldRjRmKicS\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\n\r\n--LTFyFRWteRldRjRmKicS\r\nContent-Disposition: form-data; name=\"userfile1\"; filename=\"helper.rb\"\r\nContent-Transfer-Encoding: binary\r\nContent-Type: text/plain\r\n\r\nHello World\n\n\r\n--LTFyFRWteRldRjRmKicS\r\nContent-Disposition: form-data; name=\"green[eggs]\"; filename=\"\"\r\nContent-Transfer-Encoding: binary\r\n\r\n\r\n--LTFyFRWteRldRjRmKicS\r\nContent-Disposition: form-data; name=\"green[eggs]\"; filename=\"\"\r\nContent-Transfer-Encoding: binary\r\n\r\n\r\n--LTFyFRWteRldRjRmKicS--\r\n"> expected to be =~ </Content\-Disposition:\ form\-data;\ name="green\[eggs\]";\ filename="helper\.rb"/>. 24) Failure: test_form_read_file(UploadMechTest) [./test/test_upload.rb:70]: <"--BvmhYwBnVdwlpiSVGznG\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\n\r\n--BvmhYwBnVdwlpiSVGznG\r\nContent-Disposition: form-data; name=\"foo[aaron]\"\r\n\r\ntest\r\n--BvmhYwBnVdwlpiSVGznG\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\n\r\n--BvmhYwBnVdwlpiSVGznG\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\n\r\n--BvmhYwBnVdwlpiSVGznG\r\nContent-Disposition: form-data; name=\"userfile1\"; filename=\"helper.rb\"\r\nContent-Transfer-Encoding: binary\r\nContent-Type: text/plain\r\n\r\nrequire 'test/unit'\nrequire 'rubygems'\nrequire 'www/mechanize/nokogiri'\nrequire 'webrick/httputils'\nrequire File.join(File.dirname(__FILE__),'servlets')\n\nBASE_DIR = File.dirname(__FILE__)\n\n# Move this to a test base class\nmodule MechTestHelper\n def self.fake_page(agent)\n html = <<-END\n <html><body>\n <form><input type=\"submit\" value=\"submit\" /></form>\n </body></html>\n END\n html_response = { 'content-type' => 'text/html' }\n page = WWW::Mechanize::Page.new( nil, html_response, html, 200, agent )\n end\nend\n\nclass Net::HTTP\n alias :old_do_start :do_start\n\n def do_start\n @started = true\n end\n\n SERVLETS = {\n '/gzip' => GzipServlet,\n '/form_post' => FormTest,\n '/basic_auth' => BasicAuthServlet,\n '/form post' => FormTest,\n '/response_code' => ResponseCodeTest,\n '/bad_content_type' => BadContentTypeTest,\n '/content_type_test' => ContentTypeTest,\n '/referer' => RefererServlet,\n '/file_upload' => FileUploadTest,\n '/one_cookie' => OneCookieTest,\n '/one_cookie_no_space' => OneCookieNoSpacesTest,\n '/many_cookies' => ManyCookiesTest,\n '/many_cookies_as_string' => ManyCookiesAsStringTest,\n '/send_cookies' => SendCookiesTest,\n '/if_modified_since' => ModifiedSinceServlet,\n '/http_headers' => HeaderServlet,\n '/infinite_redirect' => InfiniteRedirectTest,\n '/digest_auth' => DigestAuthServlet,\n '/verb' => VerbServlet,\n }\n\n PAGE_CACHE = {}\n\n alias :old_request :request\n\n def request(request, *data, &block)\n url = URI.parse(request.path)\n path = URI.unescape(url.path)\n\n path = '/index.html' if path == '/'\n\n res = Response.new\n request.query = WEBrick::HTTPUtils.parse_query(url.query)\n request.cookies = WEBrick::Cookie.parse(request['Cookie'])\n if SERVLETS[path]\n if request.method == \"POST\"\n if request['Content-Type'] =~ /^multipart\\/form-data/\n request.body = data.first\n else\n request.query = WEBrick::HTTPUtils.parse_query(data.first)\n end\n end\n SERVLETS[path].new({}).send(\"do_\#{request.method}\", request, res)\n else\n filename = \"htdocs\#{path.gsub(/[^\\/\\\\.\\w_\\s]/, '_')}\"\n unless PAGE_CACHE[filename]\n File.open(\"\#{BASE_DIR}/\#{filename}\", 'rb') { |file|\n PAGE_CACHE[filename] = file.read\n }\n end\n res.body = PAGE_CACHE[filename]\n end\n\n res['Content-Type'] ||= 'text/html'\n res['Content-Length'] ||= res.body.length.to_s\n res.code ||= \"200\"\n\n res.cookies.each do |cookie|\n res.add_field('Set-Cookie', cookie.to_s)\n end\n yield res if block_given?\n res\n end\nend\n\nclass Net::HTTPRequest\n attr_accessor :query, :body, :cookies, :user\nend\n\nclass Response\n include Net::HTTPHeader\n\n attr_reader :code\n attr_accessor :body, :query, :cookies\n \n def code=(c)\n @code = c.to_s\n end\n\n alias :status :code\n alias :status= :code=\n\n def initialize\n @header = {}\n @body = ''\n @code = nil\n @query = nil\n @cookies = []\n end\n\n def read_body\n yield body\n end\nend\n\r\n--BvmhYwBnVdwlpiSVGznG\r\nContent-Disposition: form-data; name=\"green[eggs]\"; filename=\"\"\r\nContent-Transfer-Encoding: binary\r\n\r\n\r\n--BvmhYwBnVdwlpiSVGznG\r\nContent-Disposition: form-data; name=\"green[eggs]\"; filename=\"\"\r\nContent-Transfer-Encoding: binary\r\n\r\n\r\n--BvmhYwBnVdwlpiSVGznG--\r\n"> expected to be =~ </Content\-Disposition:\ form\-data;\ name="green\[eggs\]";\ filename="helper\.rb"/>. 242 tests, 1239 assertions, 20 failures, 4 errors