aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/application_controller.rb12
-rw-r--r--app/controllers/general_controller.rb15
-rw-r--r--config/environments/test.rb1
-rw-r--r--spec/controllers/application_controller_spec.rb27
-rw-r--r--spec/controllers/general_controller_spec.rb10
-rw-r--r--vendor/gems/fakeweb-1.3.0/.gitignore7
-rw-r--r--vendor/gems/fakeweb-1.3.0/.specification135
-rw-r--r--vendor/gems/fakeweb-1.3.0/CHANGELOG215
-rw-r--r--vendor/gems/fakeweb-1.3.0/LICENSE.txt19
-rw-r--r--vendor/gems/fakeweb-1.3.0/README.rdoc189
-rw-r--r--vendor/gems/fakeweb-1.3.0/Rakefile67
-rw-r--r--vendor/gems/fakeweb-1.3.0/fakeweb.gemspec126
-rw-r--r--vendor/gems/fakeweb-1.3.0/lib/fake_web.rb215
-rw-r--r--vendor/gems/fakeweb-1.3.0/lib/fake_web/ext/net_http.rb72
-rw-r--r--vendor/gems/fakeweb-1.3.0/lib/fake_web/registry.rb127
-rw-r--r--vendor/gems/fakeweb-1.3.0/lib/fake_web/responder.rb122
-rw-r--r--vendor/gems/fakeweb-1.3.0/lib/fake_web/response.rb10
-rw-r--r--vendor/gems/fakeweb-1.3.0/lib/fake_web/stub_socket.rb15
-rw-r--r--vendor/gems/fakeweb-1.3.0/lib/fake_web/utility.rb87
-rw-r--r--vendor/gems/fakeweb-1.3.0/lib/fakeweb.rb2
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_from_curl12
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_with_transfer_encoding17
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_without_transfer_encoding11
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/fixtures/test_example.txt1
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/fixtures/test_txt_file3
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_allow_net_connect.rb168
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_deprecations.rb54
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_fake_authentication.rb92
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_fake_web.rb590
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_fake_web_open_uri.rb58
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_helper.rb90
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_last_request.rb29
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_missing_open_uri.rb25
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_missing_pathname.rb37
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_other_net_http_libraries.rb36
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_precedence.rb79
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_query_string.rb45
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_regexes.rb157
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_response_headers.rb79
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_trailing_slashes.rb53
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/test_utility.rb83
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/History.txt59
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/Manifest.txt7
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/README.txt54
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/Rakefile103
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/lib/net_fix.rb160
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb435
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/setup.rb1585
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/.document5
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/.gitignore5
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/LICENSE20
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/README.rdoc70
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/Rakefile62
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/VERSION1
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel.rb52
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel/net_http.rb10
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel/request.rb96
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/samuel.gemspec69
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/request_test.rb193
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/samuel_test.rb42
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/test_helper.rb66
-rw-r--r--vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/thread_test.rb32
62 files changed, 6304 insertions, 14 deletions
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 2633aca4d..f6068120d 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -504,12 +504,22 @@ class ApplicationController < ActionController::Base
default = MySociety::Config.get('ISO_COUNTRY_CODE', '')
country = ""
if !gaze.empty?
- country = open("#{gaze}/gaze-rest?f=get_country_from_ip;ip=#{request.remote_ip}").read.strip
+ country = quietly_try_to_open("#{gaze}/gaze-rest?f=get_country_from_ip;ip=#{request.remote_ip}")
end
country = default if country.empty?
return country
end
+ def quietly_try_to_open(url)
+ begin
+ result = open(url).read.strip
+ rescue OpenURI::HTTPError, SocketError
+ logger.warn("Unable to open third-party URL #{url}")
+ result = ""
+ end
+ return result
+ end
+
# URL generating functions are needed by all controllers (for redirects),
# views (for links) and mailers (for use in emails), so include them into
# all of all.
diff --git a/app/controllers/general_controller.rb b/app/controllers/general_controller.rb
index 6cdfb9d5f..d28f4deec 100644
--- a/app/controllers/general_controller.rb
+++ b/app/controllers/general_controller.rb
@@ -71,14 +71,15 @@ class GeneralController < ApplicationController
medium_cache
@feed_autodetect = []
@feed_url = "#{MySociety::Config.get('BLOG_FEED', '')}?lang=#{self.locale_from_params()}"
+ @blog_items = []
if not @feed_url.empty?
- content = open(@feed_url).read
- @data = XmlSimple.xml_in(content)
- @channel = @data['channel'][0]
- @blog_items = @channel['item']
- @feed_autodetect = [{:url => @feed_url, :title => "#{site_name} blog"}]
- else
- @blog_items = []
+ content = quietly_try_to_open(@feed_url)
+ if !content.empty?
+ @data = XmlSimple.xml_in(content)
+ @channel = @data['channel'][0]
+ @blog_items = @channel['item']
+ @feed_autodetect = [{:url => @feed_url, :title => "#{site_name} blog"}]
+ end
end
@twitter_user = MySociety::Config.get('TWITTER_USERNAME', '')
end
diff --git a/config/environments/test.rb b/config/environments/test.rb
index 8058487ad..8d6041ad9 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -18,6 +18,7 @@ config.action_controller.perform_caching = false
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
config.gem 'rspec-rails', :version => '>= 1.3.3', :lib => false unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec-rails'))
+config.gem 'fakeweb', :version => '>=1.3.0'
# Disable request forgery protection in test environment
config.action_controller.allow_forgery_protection = false
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index 875d7d224..1d6802940 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -1,10 +1,25 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+require 'fakeweb'
-describe ApplicationController, "when authenticating user" do
- integrate_views
- fixtures :users
-
-# it "blah" do
-# end
+describe ApplicationController, "when accessing third party services" do
+ it "should fail silently if the country_from_ip domain doesn't exist" do
+ config = MySociety::Config.load_default()
+ config['GAZE_URL'] = 'http://12123sdf14qsd.com'
+ country = self.controller.send :country_from_ip
+ country.should == config['ISO_COUNTRY_CODE']
+ end
+ it "should fail silently if the country_from_ip service doesn't exist" do
+ config = MySociety::Config.load_default()
+ config['GAZE_URL'] = 'http://www.google.com'
+ country = self.controller.send :country_from_ip
+ country.should == config['ISO_COUNTRY_CODE']
+ end
+ it "should fail silently if the country_from_ip service returns an error" do
+ FakeWeb.register_uri(:get, %r|.*|, :body => "Error", :status => ["500", "Error"])
+ config = MySociety::Config.load_default()
+ config['GAZE_URL'] = 'http://500.com'
+ country = self.controller.send :country_from_ip
+ country.should == config['ISO_COUNTRY_CODE']
+ end
end
diff --git a/spec/controllers/general_controller_spec.rb b/spec/controllers/general_controller_spec.rb
index 40a676d61..ad5578800 100644
--- a/spec/controllers/general_controller_spec.rb
+++ b/spec/controllers/general_controller_spec.rb
@@ -1,4 +1,14 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+require 'fakeweb'
+
+describe GeneralController, "when trying to show the blog" do
+ it "should fail silently if the blog is returning an error" do
+ FakeWeb.register_uri(:get, %r|.*|, :body => "Error", :status => ["500", "Error"])
+ get :blog
+ response.status.should == "200 OK"
+ assigns[:blog_items].count.should == 0
+ end
+end
describe GeneralController, "when searching" do
integrate_views
diff --git a/vendor/gems/fakeweb-1.3.0/.gitignore b/vendor/gems/fakeweb-1.3.0/.gitignore
new file mode 100644
index 000000000..63be0c5de
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/.gitignore
@@ -0,0 +1,7 @@
+/doc
+/rdoc
+/html
+/coverage
+/pkg
+/.idea
+*.rbc
diff --git a/vendor/gems/fakeweb-1.3.0/.specification b/vendor/gems/fakeweb-1.3.0/.specification
new file mode 100644
index 000000000..b69e9d545
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/.specification
@@ -0,0 +1,135 @@
+--- !ruby/object:Gem::Specification
+name: fakeweb
+version: !ruby/object:Gem::Version
+ hash: 27
+ prerelease:
+ segments:
+ - 1
+ - 3
+ - 0
+ version: 1.3.0
+platform: ruby
+authors:
+- Chris Kampmeier
+- Blaine Cook
+autorequire:
+bindir: bin
+cert_chain: []
+
+date: 2010-08-22 00:00:00 +01:00
+default_executable:
+dependencies:
+- !ruby/object:Gem::Dependency
+ name: mocha
+ prerelease: false
+ requirement: &id001 !ruby/object:Gem::Requirement
+ none: false
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ hash: 49
+ segments:
+ - 0
+ - 9
+ - 5
+ version: 0.9.5
+ type: :development
+ version_requirements: *id001
+description: FakeWeb is a helper for faking web requests in Ruby. It works at a global level, without modifying code or writing extensive stubs.
+email:
+- chris@kampers.net
+- romeda@gmail.com
+executables: []
+
+extensions: []
+
+extra_rdoc_files: []
+
+files:
+- test/test_allow_net_connect.rb
+- test/test_deprecations.rb
+- test/test_fake_authentication.rb
+- test/test_fake_web.rb
+- test/test_fake_web_open_uri.rb
+- test/test_helper.rb
+- test/test_last_request.rb
+- test/test_missing_open_uri.rb
+- test/test_missing_pathname.rb
+- test/test_other_net_http_libraries.rb
+- test/test_precedence.rb
+- test/test_query_string.rb
+- test/test_regexes.rb
+- test/test_response_headers.rb
+- test/test_trailing_slashes.rb
+- test/test_utility.rb
+- test/vendor/right_http_connection-1.2.4/lib/net_fix.rb
+- test/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb
+- test/vendor/right_http_connection-1.2.4/setup.rb
+- test/vendor/samuel-0.2.1/lib/samuel/net_http.rb
+- test/vendor/samuel-0.2.1/lib/samuel/request.rb
+- test/vendor/samuel-0.2.1/lib/samuel.rb
+- test/vendor/samuel-0.2.1/test/request_test.rb
+- test/vendor/samuel-0.2.1/test/samuel_test.rb
+- test/vendor/samuel-0.2.1/test/test_helper.rb
+- test/vendor/samuel-0.2.1/test/thread_test.rb
+has_rdoc: true
+homepage: http://github.com/chrisk/fakeweb
+licenses: []
+
+post_install_message:
+rdoc_options: []
+
+require_paths:
+- lib
+required_ruby_version: !ruby/object:Gem::Requirement
+ none: false
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ hash: 3
+ segments:
+ - 0
+ version: "0"
+required_rubygems_version: !ruby/object:Gem::Requirement
+ none: false
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ hash: 3
+ segments:
+ - 0
+ version: "0"
+requirements: []
+
+rubyforge_project: fakeweb
+rubygems_version: 1.6.2
+signing_key:
+specification_version: 3
+summary: A tool for faking responses to HTTP requests
+test_files:
+- test/test_allow_net_connect.rb
+- test/test_deprecations.rb
+- test/test_fake_authentication.rb
+- test/test_fake_web.rb
+- test/test_fake_web_open_uri.rb
+- test/test_helper.rb
+- test/test_last_request.rb
+- test/test_missing_open_uri.rb
+- test/test_missing_pathname.rb
+- test/test_other_net_http_libraries.rb
+- test/test_precedence.rb
+- test/test_query_string.rb
+- test/test_regexes.rb
+- test/test_response_headers.rb
+- test/test_trailing_slashes.rb
+- test/test_utility.rb
+- test/vendor/right_http_connection-1.2.4/lib/net_fix.rb
+- test/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb
+- test/vendor/right_http_connection-1.2.4/setup.rb
+- test/vendor/samuel-0.2.1/lib/samuel/net_http.rb
+- test/vendor/samuel-0.2.1/lib/samuel/request.rb
+- test/vendor/samuel-0.2.1/lib/samuel.rb
+- test/vendor/samuel-0.2.1/test/request_test.rb
+- test/vendor/samuel-0.2.1/test/samuel_test.rb
+- test/vendor/samuel-0.2.1/test/test_helper.rb
+- test/vendor/samuel-0.2.1/test/thread_test.rb
diff --git a/vendor/gems/fakeweb-1.3.0/CHANGELOG b/vendor/gems/fakeweb-1.3.0/CHANGELOG
new file mode 100644
index 000000000..e626352f6
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/CHANGELOG
@@ -0,0 +1,215 @@
+fakeweb (1.3.0)
+
+* improve response header registration so you can pass an array to set a header
+ more than once [Myron Marston]
+
+* fix an exception when the response's :body option was set to nil [Chris Zingel]
+
+* fix that stubbed requests weren't mutating the Net::HTTP request object to set
+ the body and content-length, like real requests do [Chris Kampmeier]
+
+* add FakeWeb.last_request [Chris Kampmeier]
+
+* assigning a String or Regexp to FakeWeb.allow_net_connect= sets a whitelist
+ for outbound requests [Dan Dofter, Tim Carey-Smith, Ben Woosley]
+
+
+fakeweb (1.2.8)
+
+* support Pathname objects where a filename is expected [Chris Kampmeier]
+
+* fix compatibility with Ruby 1.9.2 [Chris Kampmeier]
+
+* simplify storage of FakeWeb::VERSION [Josh Peek, Woody Peterson, Ben Woosley]
+
+
+fakeweb (1.2.7)
+
+* revert to sorting query params before matching requests against regexps,
+ instead of the 1.2.6 behavior that tried every possible order combination;
+ that was factorial-time, which made matching hang for requests with long query
+ strings [Jason Wadsworth, David Dollar, Blaine Cook]
+
+* print a warning when FakeWeb is loaded before RightHttpConnection or after
+ Samuel, other libs that patch Net::HTTP [Chris Kampmeier, Ben Brinckerhoff]
+
+
+fakeweb (1.2.6)
+
+* fix that query params in a regex would have to be sorted for it to ever match
+ a request URI [Chris Kampmeier, Ben Hall]
+
+* improve regex handling so registration with an explicit port (like
+ /example.com:80/) matches a request that uses an implied port
+ (like "http://example.com/") [Chris Kampmeier, Dan Dofter]
+
+* refactor URI registry to reduce duplication; now about twice as fast at
+ handling requests [Chris Kampmeier]
+
+* Add FakeWeb::VERSION so you can programmatically determine what version of
+ FakeWeb is loaded without using RubyGems [Chris Kampmeier, Chris Wanstrath]
+
+
+fakeweb (1.2.5)
+
+* fix handling of userinfo strings that contain percent-encoded unsafe
+ characters [Chris Kampmeier, Ken Mayer]
+
+* fix that exact matches against strings/URIs with the :any method had a lower
+ precedence than regex matches using a real HTTP method (exact matches now
+ always take precedence) [Chris Kampmeier]
+
+* change request handling to raise an exception when more than one registered
+ regex matches a request URI [Chris Kampmeier]
+
+
+fakeweb (1.2.4)
+
+* add experimental support for matching URIs via regular expressions
+ [Jacqui Maher, Tiago Albineli Motta, Peter Wagene]
+
+* fix an exception when registering with the :response option and a string that
+ is the same as the name of a directory in the current path [Chris Kampmeier]
+
+* DEPRECATION: Calling FakeWeb.register_uri with a :string or :file option is
+ now deprecated. Both options have been replaced with a unified :body option,
+ since they supply the response body (as opposed to :response, which supplies
+ the full response including headers) [Chris Kampmeier]
+
+* add support for specifying HTTP headers as options to FakeWeb.register_uri
+ when using the :string or :file response types, since those methods only
+ specify a response body [David Michael, Chris Kampmeier]
+
+* DEPRECATION: Calling FakeWeb.register_uri and FakeWeb.registered_uri? without
+ an HTTP method as the first argument is now deprecated. To match against any
+ HTTP method (the pre-1.2.0 behavior), use :any [Chris Kampmeier]
+
+
+fakeweb (1.2.3)
+
+* fix the #http_version of :file and :string responses, which was returning the
+ request URI instead of something sensible like "1.0" [Chris Kampmeier]
+
+* add method aliases in the Net::HTTP patch to eliminate warnings when running
+ with -w [Joshua Clingenpeel]
+
+* fix that removing the redefinition of OpenURI::HTTPError in 1.2.0 caused
+ :exception responses to raise when OpenURI isn't available [Chris Kampmeier]
+
+* fix registering an :exception response with classes that require arguments for
+ instantiation, like Interrupt's subclasses [Chris Kampmeier]
+
+
+fakeweb (1.2.2)
+
+* fix that HTTP Digest and OAuth requests could raise URI::InvalidURIErrors
+ [Bill Kocik, Chris Kampmeier]
+
+
+fakeweb (1.2.1)
+
+* fix that query parameters are handled correctly when registering with a URI
+ object [Anselmo Alves, Chris Kampmeier]
+
+* fix an exception when registering with the :response option and a string
+ containing "\0" [Jonathan Baudanza, Chris Kampmeier]
+
+* fix that trailing slashes were considered significant for requests to the root
+ of a domain [Chris Kampmeier]
+
+* add support for HTTP basic authentication via userinfo strings in URIs
+ [Michael Bleigh]
+
+
+fakeweb (1.2.0)
+
+* add lib/fakeweb.rb so you can require "fakeweb" as well [Chris Kampmeier]
+
+* fix compatibility with Ruby 1.9.1 [Chris Kampmeier]
+
+* fix that newlines in file-based responses could be doubled in the response
+ object's body [Mark Menard, Chris Kampmeier]
+
+* fix unnecessary munging of the transfer-encoding header, which improves
+ compatibility with mechanize [Mark Menard]
+
+* fix a test and the RCov dependency to be compatible with JRuby [Mark Menard]
+
+* remove an unnecessary redefinition of OpenURI::HTTPError [Josh Nichols]
+
+* rearrange implementation code into separate files, one per class [Josh Nichols]
+
+* fix a bug where FakeWeb.response_for would raise if the request wasn't
+ registered [Chris Kampmeier]
+
+* add HTTP method support, so FakeWeb takes both the URI and method into
+ account for registration, requests, and responses. Backwards-compatible with
+ the old method signatures, which didn't have a method param. [Chris Kampmeier]
+
+* start work on Ruby 1.9 compatibility [Chris Kampmeier]
+
+* add FakeWeb.allow_net_connect= to enable/disable the pass-through to
+ Net::HTTP for unregistered URIs [Mislav Marohnić, Chris Kampmeier]
+
+* remove setup.rb, since most people use RubyGems [Mislav Marohnić]
+
+* fix that 'http://example.com/?' (empty query) matches a registered
+ 'http://example.com/', and vice-versa [Mislav Marohnić]
+
+* improve the test suite to not rely on an internet connection [Chris Kampmeier]
+
+* use `rake test` instead of `rake tests` [Josh Nichols]
+
+* fix an incompatibility with Ruby 1.8.6 p36 where you'd get "Errno::EINTR:
+ Interrupted system call" exceptions in Socket#sysread for any non-faked
+ request [Chris Kampmeier]
+
+* response rotation: you can now optionally call FakeWeb.register_uri with an
+ array of options hashes; these are used, in order, to respond to
+ repeated requests (to repeat a response more than once before rotating, use
+ the :times option). Once you run out of responses, further requests always
+ receive the last response. [Michael Shapiro]
+
+* add support for Net::HTTP's undocumented full-URI request style (fixes
+ URI::InvalidURIErrors that you might see in older libraries) [Chris Kampmeier]
+
+* sort query params before storing internally, so that
+ http://example.com/?a=1&b=2 and http://example.com/?b=2&a=1 are considered the
+ same URL (although this is technically incorrect, it's much more
+ convenient--most web apps work that way, and Net::HTTP's use of a hash to pass
+ query params means that the order in which FakeWeb stores them can be
+ unpredictable) [Chris Kampmeier]
+
+* add support for ports in URLs, so that http://example.com/ and
+ http://example.com:3000/ are not the same [Chris Kampmeier]
+
+* fix for non-faked SSL requests failing with "Unable to create local socket"
+ [Chris Kampmeier]
+
+* update Rakefile to fix warning about deprecated code [Chris Kampmeier]
+
+
+fakeweb (1.1.2)
+
+* add required dependencies to GemSpec to ensure that tests pass in firebrigade
+ (http://firebrigade.seattlerb.org/) [Blaine Cook]
+
+
+fakeweb (1.1.1)
+
+* fix for non-existence of :string method on File as presented by open-uri
+ [Blaine Cook]
+
+* fix for curl example test - google redirects to ccTLDs for those outside US
+ [Blaine Cook]
+
+
+fakeweb (1.1.0)
+
+* update code to correspond to ruby 1.8.4 (breaks compatibility with ruby 1.8.2)
+ [Blaine Cook]
+
+
+fakeweb (1.0.0)
+
+ * initial import [Blaine Cook]
diff --git a/vendor/gems/fakeweb-1.3.0/LICENSE.txt b/vendor/gems/fakeweb-1.3.0/LICENSE.txt
new file mode 100644
index 000000000..ecae84703
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/LICENSE.txt
@@ -0,0 +1,19 @@
+Copyright 2006-2010 Blaine Cook, Chris Kampmeier, and other contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/gems/fakeweb-1.3.0/README.rdoc b/vendor/gems/fakeweb-1.3.0/README.rdoc
new file mode 100644
index 000000000..33115325b
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/README.rdoc
@@ -0,0 +1,189 @@
+= FakeWeb
+
+FakeWeb is a helper for faking web requests in Ruby. It works at a global
+level, without modifying code or writing extensive stubs.
+
+
+== Installation
+
+ gem install fakeweb
+
+Note: the gem was previously available as +FakeWeb+ (capital letters), but now
+all versions are simply registered as +fakeweb+. If you have any old +FakeWeb+
+gems lying around, remove them: <tt>gem uninstall FakeWeb</tt>
+
+
+== Help and discussion
+
+RDocs for the current release are available at http://fakeweb.rubyforge.org.
+
+There's a mailing list for questions and discussion at
+http://groups.google.com/group/fakeweb-users.
+
+The main source repository is http://github.com/chrisk/fakeweb.
+
+== Examples
+
+Start by requiring FakeWeb:
+
+ require 'fakeweb'
+
+=== Registering basic string responses
+
+ FakeWeb.register_uri(:get, "http://example.com/test1", :body => "Hello World!")
+
+ Net::HTTP.get(URI.parse("http://example.com/test1"))
+ => "Hello World!"
+
+ Net::HTTP.get(URI.parse("http://example.com/test2"))
+ => FakeWeb is bypassed and the response from a real request is returned
+
+You can also call <tt>register_uri</tt> with a regular expression, to match
+more than one URI.
+
+ FakeWeb.register_uri(:get, %r|http://example\.com/|, :body => "Hello World!")
+
+ Net::HTTP.get(URI.parse("http://example.com/test3"))
+ => "Hello World!"
+
+=== Replaying a recorded response
+
+ page = `curl -is http://www.google.com/`
+ FakeWeb.register_uri(:get, "http://www.google.com/", :response => page)
+
+ Net::HTTP.get(URI.parse("http://www.google.com/"))
+ # => Full response, including headers
+
+=== Adding a custom status to the response
+
+ FakeWeb.register_uri(:get, "http://example.com/", :body => "Nothing to be found 'round here",
+ :status => ["404", "Not Found"])
+
+ Net::HTTP.start("example.com") do |req|
+ response = req.get("/")
+ response.code # => "404"
+ response.message # => "Not Found"
+ response.body # => "Nothing to be found 'round here"
+ end
+
+=== Responding to any HTTP method
+
+ FakeWeb.register_uri(:any, "http://example.com", :body => "response for any HTTP method")
+
+If you use the <tt>:any</tt> symbol, the URI you specify will be completely
+stubbed out (regardless of the HTTP method of the request). This can be useful
+for RPC-style services, where the HTTP method isn't significant. (Older
+versions of FakeWeb always behaved like this, and didn't accept the first
++method+ argument above; this syntax is now deprecated.)
+
+=== Rotating responses
+
+You can optionally call <tt>FakeWeb.register_uri</tt> with an array of options
+hashes; these are used, in order, to respond to repeated requests. Once you run
+out of responses, further requests always receive the last response. (You can
+also send a response more than once before rotating, by specifying a
+<tt>:times</tt> option for that response.)
+
+ FakeWeb.register_uri(:delete, "http://example.com/posts/1",
+ [{:body => "Post 1 deleted.", :status => ["200", "OK"]},
+ {:body => "Post not found", :status => ["404", "Not Found"]}])
+
+ Net::HTTP.start("example.com") do |req|
+ req.delete("/posts/1").body # => "Post 1 deleted"
+ req.delete("/posts/1").body # => "Post not found"
+ req.delete("/posts/1").body # => "Post not found"
+ end
+
+=== Using HTTP basic authentication
+
+You can fake requests that use basic authentication by adding +userinfo+ strings
+to your URIs:
+
+ FakeWeb.register_uri(:get, "http://example.com/secret", :body => "Unauthorized", :status => ["401", "Unauthorized"])
+ FakeWeb.register_uri(:get, "http://user:pass@example.com/secret", :body => "Authorized")
+
+ Net::HTTP.start("example.com") do |http|
+ req = Net::HTTP::Get.new("/secret")
+ http.request(req) # => "Unauthorized"
+ req.basic_auth("user", "pass")
+ http.request(req) # => "Authorized"
+ end
+
+=== Clearing registered URIs
+
+The FakeWeb registry is a singleton that lasts for the duration of your program,
+maintaining every fake response you register. If needed, you can clean out the
+registry and remove all registered URIs:
+
+ FakeWeb.clean_registry
+
+=== Blocking all real requests
+
+When you're using FakeWeb to replace _all_ of your requests, it's useful to
+catch when requests are made for unregistered URIs (unlike the default
+behavior, which is to pass those requests through to Net::HTTP as usual).
+
+ FakeWeb.allow_net_connect = false
+ Net::HTTP.get(URI.parse("http://example.com/"))
+ => raises FakeWeb::NetConnectNotAllowedError
+
+ FakeWeb.allow_net_connect = true
+ Net::HTTP.get(URI.parse("http://example.com/"))
+ => FakeWeb is bypassed and the response from a real request is returned
+
+It's recommended that you set <tt>FakeWeb.allow_net_connect = false</tt> in the
+setup for your tests.
+
+==== Allowing requests to a specific server
+
+If you want to prevent your tests from hitting the internet while allowing
+access to a specific server for integration testing, you can assign a URI or
++Regexp+ to be used as a whitelist for outbound requests:
+
+ FakeWeb.allow_net_connect = %r[^https?://localhost]
+ Net::HTTP.get(URI.parse("http://localhost/path")) # => allowed
+ Net::HTTP.get(URI.parse("http://example.com/")) # => raises FakeWeb::NetConnectNotAllowedError
+
+=== Specifying HTTP response headers
+
+When you register a response using the <tt>:body</tt> option, you're only
+setting the body of the response. If you want to add headers to these responses,
+simply add the header as an option to +register_uri+:
+
+ FakeWeb.register_uri(:get, "http://example.com/hello.txt", :body => "Hello", :content_type => "text/plain")
+
+This sets the "Content-Type" header in the response.
+
+=== Checking the last request
+
+It's often useful to retrieve the last request made by your code, so you can
+write tests for its content. FakeWeb keeps track of the last request, whether it
+was stubbed or not:
+
+ Net::HTTP.get(URI.parse("http://example.com"))
+ FakeWeb.last_request # => Net::HTTP::Get request object
+
+== More info
+
+FakeWeb lets you decouple your test environment from live services without
+modifying code or writing extensive stubs.
+
+In addition to the conceptual advantage of having idempotent request
+behaviour, FakeWeb makes tests run faster than if they were made to remote (or
+even local) web servers. It also makes it possible to run tests without a
+network connection or in situations where the server is behind a firewall or
+has host-based access controls.
+
+FakeWeb works with anything based on Net::HTTP--both higher-level wrappers,
+like OpenURI, as well as a ton of libraries for popular web services.
+
+
+== Known Issues
+
+* Request bodies are ignored, including PUT and POST parameters. If you need
+ different responses for different request bodies, you need to request
+ different URLs, and register different responses for each. (Query strings are
+ fully supported, though.) We're currently considering how the API should
+ change to add support for request bodies in 1.3.0. Your input would be really
+ helpful: see http://groups.google.com/group/fakeweb-users/browse_thread/thread/44d190a6b12e4273
+ for a discussion of some different options. Thanks!
diff --git a/vendor/gems/fakeweb-1.3.0/Rakefile b/vendor/gems/fakeweb-1.3.0/Rakefile
new file mode 100644
index 000000000..e3c5298c6
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/Rakefile
@@ -0,0 +1,67 @@
+require 'rubygems'
+require 'rake'
+
+version = '1.3.0'
+
+begin
+ require 'jeweler'
+ Jeweler::Tasks.new do |gem|
+ gem.name = "fakeweb"
+ gem.rubyforge_project = "fakeweb"
+ gem.version = version
+ gem.summary = "A tool for faking responses to HTTP requests"
+ gem.description = "FakeWeb is a helper for faking web requests in Ruby. It works at a global level, without modifying code or writing extensive stubs."
+ gem.email = ["chris@kampers.net", "romeda@gmail.com"]
+ gem.authors = ["Chris Kampmeier", "Blaine Cook"]
+ gem.homepage = "http://github.com/chrisk/fakeweb"
+ gem.add_development_dependency "mocha", ">= 0.9.5"
+ end
+rescue LoadError
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
+end
+
+
+require 'rake/testtask'
+Rake::TestTask.new(:test) do |test|
+ test.test_files = FileList["test/**/*.rb"].exclude("test/test_helper.rb", "test/vendor")
+ test.libs << "test"
+ test.verbose = false
+ test.warning = true
+end
+
+task :default => [:check_dependencies, :test]
+
+
+begin
+ require 'rcov/rcovtask'
+ Rcov::RcovTask.new do |t|
+ t.test_files = FileList["test/**/*.rb"].exclude("test/test_helper.rb", "test/vendor")
+ t.libs << "test"
+ t.rcov_opts << "--sort coverage"
+ t.rcov_opts << "--exclude gems"
+ t.warning = true
+ end
+rescue LoadError
+ print "rcov support disabled "
+ if RUBY_PLATFORM =~ /java/
+ puts "(running under JRuby)"
+ else
+ puts "(install RCov to enable the `rcov` task)"
+ end
+end
+
+
+begin
+ require 'sdoc'
+ require 'rdoc/task'
+ Rake::RDocTask.new do |rdoc|
+ rdoc.main = "README.rdoc"
+ rdoc.rdoc_files.include("README.rdoc", "CHANGELOG", "LICENSE.txt", "lib/*.rb")
+ rdoc.title = "FakeWeb #{version} API Documentation"
+ rdoc.rdoc_dir = "doc"
+ rdoc.template = "direct"
+ rdoc.options << "--line-numbers" << "--show-hash" << "--charset=utf-8"
+ end
+rescue LoadError
+ puts "SDoc (or a dependency) not available. Install it with: gem install sdoc"
+end
diff --git a/vendor/gems/fakeweb-1.3.0/fakeweb.gemspec b/vendor/gems/fakeweb-1.3.0/fakeweb.gemspec
new file mode 100644
index 000000000..39b23f001
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/fakeweb.gemspec
@@ -0,0 +1,126 @@
+# Generated by jeweler
+# DO NOT EDIT THIS FILE DIRECTLY
+# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
+ s.name = %q{fakeweb}
+ s.version = "1.3.0"
+
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+ s.authors = ["Chris Kampmeier", "Blaine Cook"]
+ s.date = %q{2010-08-22}
+ s.description = %q{FakeWeb is a helper for faking web requests in Ruby. It works at a global level, without modifying code or writing extensive stubs.}
+ s.email = ["chris@kampers.net", "romeda@gmail.com"]
+ s.extra_rdoc_files = [
+ "LICENSE.txt",
+ "README.rdoc"
+ ]
+ s.files = [
+ ".autotest",
+ ".gitignore",
+ "CHANGELOG",
+ "LICENSE.txt",
+ "README.rdoc",
+ "Rakefile",
+ "fakeweb.gemspec",
+ "lib/fake_web.rb",
+ "lib/fake_web/ext/net_http.rb",
+ "lib/fake_web/registry.rb",
+ "lib/fake_web/responder.rb",
+ "lib/fake_web/response.rb",
+ "lib/fake_web/stub_socket.rb",
+ "lib/fake_web/utility.rb",
+ "lib/fakeweb.rb",
+ "test/fixtures/google_response_from_curl",
+ "test/fixtures/google_response_with_transfer_encoding",
+ "test/fixtures/google_response_without_transfer_encoding",
+ "test/fixtures/test_example.txt",
+ "test/fixtures/test_txt_file",
+ "test/test_allow_net_connect.rb",
+ "test/test_deprecations.rb",
+ "test/test_fake_authentication.rb",
+ "test/test_fake_web.rb",
+ "test/test_fake_web_open_uri.rb",
+ "test/test_helper.rb",
+ "test/test_last_request.rb",
+ "test/test_missing_open_uri.rb",
+ "test/test_missing_pathname.rb",
+ "test/test_other_net_http_libraries.rb",
+ "test/test_precedence.rb",
+ "test/test_query_string.rb",
+ "test/test_regexes.rb",
+ "test/test_response_headers.rb",
+ "test/test_trailing_slashes.rb",
+ "test/test_utility.rb",
+ "test/vendor/right_http_connection-1.2.4/History.txt",
+ "test/vendor/right_http_connection-1.2.4/Manifest.txt",
+ "test/vendor/right_http_connection-1.2.4/README.txt",
+ "test/vendor/right_http_connection-1.2.4/Rakefile",
+ "test/vendor/right_http_connection-1.2.4/lib/net_fix.rb",
+ "test/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb",
+ "test/vendor/right_http_connection-1.2.4/setup.rb",
+ "test/vendor/samuel-0.2.1/.document",
+ "test/vendor/samuel-0.2.1/.gitignore",
+ "test/vendor/samuel-0.2.1/LICENSE",
+ "test/vendor/samuel-0.2.1/README.rdoc",
+ "test/vendor/samuel-0.2.1/Rakefile",
+ "test/vendor/samuel-0.2.1/VERSION",
+ "test/vendor/samuel-0.2.1/lib/samuel.rb",
+ "test/vendor/samuel-0.2.1/lib/samuel/net_http.rb",
+ "test/vendor/samuel-0.2.1/lib/samuel/request.rb",
+ "test/vendor/samuel-0.2.1/samuel.gemspec",
+ "test/vendor/samuel-0.2.1/test/request_test.rb",
+ "test/vendor/samuel-0.2.1/test/samuel_test.rb",
+ "test/vendor/samuel-0.2.1/test/test_helper.rb",
+ "test/vendor/samuel-0.2.1/test/thread_test.rb"
+ ]
+ s.homepage = %q{http://github.com/chrisk/fakeweb}
+ s.rdoc_options = ["--charset=UTF-8"]
+ s.require_paths = ["lib"]
+ s.rubyforge_project = %q{fakeweb}
+ s.rubygems_version = %q{1.3.7}
+ s.summary = %q{A tool for faking responses to HTTP requests}
+ s.test_files = [
+ "test/test_allow_net_connect.rb",
+ "test/test_deprecations.rb",
+ "test/test_fake_authentication.rb",
+ "test/test_fake_web.rb",
+ "test/test_fake_web_open_uri.rb",
+ "test/test_helper.rb",
+ "test/test_last_request.rb",
+ "test/test_missing_open_uri.rb",
+ "test/test_missing_pathname.rb",
+ "test/test_other_net_http_libraries.rb",
+ "test/test_precedence.rb",
+ "test/test_query_string.rb",
+ "test/test_regexes.rb",
+ "test/test_response_headers.rb",
+ "test/test_trailing_slashes.rb",
+ "test/test_utility.rb",
+ "test/vendor/right_http_connection-1.2.4/lib/net_fix.rb",
+ "test/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb",
+ "test/vendor/right_http_connection-1.2.4/setup.rb",
+ "test/vendor/samuel-0.2.1/lib/samuel/net_http.rb",
+ "test/vendor/samuel-0.2.1/lib/samuel/request.rb",
+ "test/vendor/samuel-0.2.1/lib/samuel.rb",
+ "test/vendor/samuel-0.2.1/test/request_test.rb",
+ "test/vendor/samuel-0.2.1/test/samuel_test.rb",
+ "test/vendor/samuel-0.2.1/test/test_helper.rb",
+ "test/vendor/samuel-0.2.1/test/thread_test.rb"
+ ]
+
+ if s.respond_to? :specification_version then
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ s.specification_version = 3
+
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+ s.add_development_dependency(%q<mocha>, [">= 0.9.5"])
+ else
+ s.add_dependency(%q<mocha>, [">= 0.9.5"])
+ end
+ else
+ s.add_dependency(%q<mocha>, [">= 0.9.5"])
+ end
+end
+
diff --git a/vendor/gems/fakeweb-1.3.0/lib/fake_web.rb b/vendor/gems/fakeweb-1.3.0/lib/fake_web.rb
new file mode 100644
index 000000000..77fbdaec4
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/lib/fake_web.rb
@@ -0,0 +1,215 @@
+require 'singleton'
+
+require 'fake_web/ext/net_http'
+require 'fake_web/registry'
+require 'fake_web/response'
+require 'fake_web/responder'
+require 'fake_web/stub_socket'
+require 'fake_web/utility'
+
+FakeWeb::Utility.record_loaded_net_http_replacement_libs
+FakeWeb::Utility.puts_warning_for_net_http_around_advice_libs_if_needed
+
+module FakeWeb
+
+ # Returns the version string for the copy of FakeWeb you have loaded.
+ VERSION = '1.3.0'
+
+ # Resets the FakeWeb Registry. This will force all subsequent web requests to
+ # behave as real requests.
+ def self.clean_registry
+ Registry.instance.clean_registry
+ end
+
+ # Enables or disables real HTTP connections for requests that don't match
+ # registered URIs.
+ #
+ # If you set <tt>FakeWeb.allow_net_connect = false</tt> and subsequently try
+ # to make a request to a URI you haven't registered with #register_uri, a
+ # NetConnectNotAllowedError will be raised. This is handy when you want to
+ # make sure your tests are self-contained, or want to catch the scenario
+ # when a URI is changed in implementation code without a corresponding test
+ # change.
+ #
+ # When <tt>FakeWeb.allow_net_connect = true</tt> (the default), requests to
+ # URIs not stubbed with FakeWeb are passed through to Net::HTTP.
+ #
+ # If you assign a +String+, +URI+, or +Regexp+ object, unstubbed requests
+ # will be allowed if they match that value. This is useful when you want to
+ # allow access to a local server for integration testing, while still
+ # preventing your tests from using the internet.
+ def self.allow_net_connect=(allowed)
+ case allowed
+ when String, URI, Regexp
+ @allow_all_connections = false
+ Registry.instance.register_passthrough_uri(allowed)
+ else
+ @allow_all_connections = allowed
+ Registry.instance.remove_passthrough_uri
+ end
+ end
+
+ # Enable pass-through to Net::HTTP by default.
+ self.allow_net_connect = true
+
+ # Returns +true+ if requests to URIs not registered with FakeWeb are passed
+ # through to Net::HTTP for normal processing (the default). Returns +false+
+ # if an exception is raised for these requests.
+ #
+ # If you've assigned a +String+, +URI+, or +Regexp+ to
+ # <tt>FakeWeb.allow_net_connect=</tt>, you must supply a URI to check
+ # against that filter. Otherwise, an ArgumentError will be raised.
+ def self.allow_net_connect?(uri = nil)
+ if Registry.instance.passthrough_uri_map.any?
+ raise ArgumentError, "You must supply a URI to test" if uri.nil?
+ Registry.instance.passthrough_uri_matches?(uri)
+ else
+ @allow_all_connections
+ end
+ end
+
+ # This exception is raised if you set <tt>FakeWeb.allow_net_connect =
+ # false</tt> and subsequently try to make a request to a URI you haven't
+ # stubbed.
+ class NetConnectNotAllowedError < StandardError; end;
+
+ # This exception is raised if a Net::HTTP request matches more than one of
+ # the stubs you've registered. To fix the problem, remove a duplicate
+ # registration or disambiguate any regular expressions by making them more
+ # specific.
+ class MultipleMatchingURIsError < StandardError; end;
+
+ # call-seq:
+ # FakeWeb.register_uri(method, uri, options)
+ #
+ # Register requests using the HTTP method specified by the symbol +method+
+ # for +uri+ to be handled according to +options+. If you specify the method
+ # <tt>:any</tt>, the response will be reigstered for any request for +uri+.
+ # +uri+ can be a +String+, +URI+, or +Regexp+ object. +options+ must be either
+ # a +Hash+ or an +Array+ of +Hashes+ (see below), which must contain one of
+ # these two keys:
+ #
+ # <tt>:body</tt>::
+ # A string which is used as the body of the response. If the string refers
+ # to a valid filesystem path, the contents of that file will be read and used
+ # as the body of the response instead. (This used to be two options,
+ # <tt>:string</tt> and <tt>:file</tt>, respectively. These are now deprecated.)
+ # <tt>:response</tt>::
+ # Either a <tt>Net::HTTPResponse</tt>, an +IO+, or a +String+ which is used
+ # as the full response for the request.
+ #
+ # The easier way by far is to pass the <tt>:response</tt> option to
+ # +register_uri+ as a +String+ or an (open for reads) +IO+ object which
+ # will be used as the complete HTTP response, including headers and body.
+ # If the string points to a readable file, this file will be used as the
+ # content for the request.
+ #
+ # To obtain a complete response document, you can use the +curl+ command,
+ # like so:
+ #
+ # curl -i http://example.com > response_from_example.com
+ #
+ # which can then be used in your test environment like so:
+ #
+ # FakeWeb.register_uri(:get, "http://example.com", :response => "response_from_example.com")
+ #
+ # See the <tt>Net::HTTPResponse</tt>
+ # documentation[http://ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTPResponse.html]
+ # for more information on creating custom response objects.
+ #
+ # +options+ may also be an +Array+ containing a list of the above-described
+ # +Hash+. In this case, FakeWeb will rotate through each response. You can
+ # optionally repeat a response more than once before rotating:
+ #
+ # <tt>:times</tt>::
+ # The number of times this response will be used before moving on to the
+ # next one. The last response will be repeated indefinitely, regardless of
+ # its <tt>:times</tt> parameter.
+ #
+ # Two optional arguments are also accepted:
+ #
+ # <tt>:status</tt>::
+ # Passing <tt>:status</tt> as a two-value array will set the response code
+ # and message. The defaults are <tt>200</tt> and <tt>OK</tt>, respectively.
+ # Example:
+ # FakeWeb.register_uri(:get, "http://example.com", :body => "Go away!", :status => [404, "Not Found"])
+ # <tt>:exception</tt>::
+ # The argument passed via <tt>:exception</tt> will be raised when the
+ # specified URL is requested. Any +Exception+ class is valid. Example:
+ # FakeWeb.register_uri(:get, "http://example.com", :exception => Net::HTTPError)
+ #
+ # If you're using the <tt>:body</tt> response type, you can pass additional
+ # options to specify the HTTP headers to be used in the response. Example:
+ #
+ # FakeWeb.register_uri(:get, "http://example.com/index.txt", :body => "Hello", :content_type => "text/plain")
+ #
+ # You can also pass an array of header values to include a header in the
+ # response more than once:
+ #
+ # FakeWeb.register_uri(:get, "http://example.com", :set_cookie => ["name=value", "example=1"])
+ def self.register_uri(*args)
+ case args.length
+ when 3
+ Registry.instance.register_uri(*args)
+ when 2
+ print_missing_http_method_deprecation_warning(*args)
+ Registry.instance.register_uri(:any, *args)
+ else
+ raise ArgumentError.new("wrong number of arguments (#{args.length} for 3)")
+ end
+ end
+
+ # call-seq:
+ # FakeWeb.response_for(method, uri)
+ #
+ # Returns the faked Net::HTTPResponse object associated with +method+ and +uri+.
+ def self.response_for(*args, &block) #:nodoc: :yields: response
+ case args.length
+ when 2
+ Registry.instance.response_for(*args, &block)
+ when 1
+ print_missing_http_method_deprecation_warning(*args)
+ Registry.instance.response_for(:any, *args, &block)
+ else
+ raise ArgumentError.new("wrong number of arguments (#{args.length} for 2)")
+ end
+ end
+
+ # call-seq:
+ # FakeWeb.registered_uri?(method, uri)
+ #
+ # Returns true if a +method+ request for +uri+ is registered with FakeWeb.
+ # Specify a method of <tt>:any</tt> to check against all HTTP methods.
+ def self.registered_uri?(*args)
+ case args.length
+ when 2
+ Registry.instance.registered_uri?(*args)
+ when 1
+ print_missing_http_method_deprecation_warning(*args)
+ Registry.instance.registered_uri?(:any, *args)
+ else
+ raise ArgumentError.new("wrong number of arguments (#{args.length} for 2)")
+ end
+ end
+
+ # Returns the request object from the last request made via Net::HTTP.
+ def self.last_request
+ @last_request
+ end
+
+ def self.last_request=(request) #:nodoc:
+ @last_request = request
+ end
+
+ private
+
+ def self.print_missing_http_method_deprecation_warning(*args)
+ method = caller.first.match(/`(.*?)'/)[1]
+ new_args = args.map { |a| a.inspect }.unshift(":any")
+ new_args.last.gsub!(/^\{|\}$/, "").gsub!("=>", " => ") if args.last.is_a?(Hash)
+ $stderr.puts
+ $stderr.puts "Deprecation warning: FakeWeb requires an HTTP method argument (or use :any). Try this:"
+ $stderr.puts " FakeWeb.#{method}(#{new_args.join(', ')})"
+ $stderr.puts "Called at #{caller[1]}"
+ end
+end
diff --git a/vendor/gems/fakeweb-1.3.0/lib/fake_web/ext/net_http.rb b/vendor/gems/fakeweb-1.3.0/lib/fake_web/ext/net_http.rb
new file mode 100644
index 000000000..4ff3e9a10
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/lib/fake_web/ext/net_http.rb
@@ -0,0 +1,72 @@
+require 'net/http'
+require 'net/https'
+require 'stringio'
+
+module Net #:nodoc: all
+
+ class BufferedIO
+ def initialize_with_fakeweb(io, debug_output = nil)
+ @read_timeout = 60
+ @rbuf = ''
+ @debug_output = debug_output
+
+ @io = case io
+ when Socket, OpenSSL::SSL::SSLSocket, IO
+ io
+ when String
+ if !io.include?("\0") && File.exists?(io) && !File.directory?(io)
+ File.open(io, "r")
+ else
+ StringIO.new(io)
+ end
+ end
+ raise "Unable to create local socket" unless @io
+ end
+ alias_method :initialize_without_fakeweb, :initialize
+ alias_method :initialize, :initialize_with_fakeweb
+ end
+
+ class HTTP
+ class << self
+ def socket_type_with_fakeweb
+ FakeWeb::StubSocket
+ end
+ alias_method :socket_type_without_fakeweb, :socket_type
+ alias_method :socket_type, :socket_type_with_fakeweb
+ end
+
+ def request_with_fakeweb(request, body = nil, &block)
+ FakeWeb.last_request = request
+
+ uri = FakeWeb::Utility.request_uri_as_string(self, request)
+ method = request.method.downcase.to_sym
+
+ if FakeWeb.registered_uri?(method, uri)
+ @socket = Net::HTTP.socket_type.new
+ FakeWeb::Utility.produce_side_effects_of_net_http_request(request, body)
+ FakeWeb.response_for(method, uri, &block)
+ elsif FakeWeb.allow_net_connect?(uri)
+ connect_without_fakeweb
+ request_without_fakeweb(request, body, &block)
+ else
+ uri = FakeWeb::Utility.strip_default_port_from_uri(uri)
+ raise FakeWeb::NetConnectNotAllowedError,
+ "Real HTTP connections are disabled. Unregistered request: #{request.method} #{uri}"
+ end
+ end
+ alias_method :request_without_fakeweb, :request
+ alias_method :request, :request_with_fakeweb
+
+
+ def connect_with_fakeweb
+ unless @@alredy_checked_for_net_http_replacement_libs ||= false
+ FakeWeb::Utility.puts_warning_for_net_http_replacement_libs_if_needed
+ @@alredy_checked_for_net_http_replacement_libs = true
+ end
+ nil
+ end
+ alias_method :connect_without_fakeweb, :connect
+ alias_method :connect, :connect_with_fakeweb
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/lib/fake_web/registry.rb b/vendor/gems/fakeweb-1.3.0/lib/fake_web/registry.rb
new file mode 100644
index 000000000..9a4a34e68
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/lib/fake_web/registry.rb
@@ -0,0 +1,127 @@
+module FakeWeb
+ class Registry #:nodoc:
+ include Singleton
+
+ attr_accessor :uri_map, :passthrough_uri_map
+
+ def initialize
+ clean_registry
+ end
+
+ def clean_registry
+ self.uri_map = Hash.new { |hash, key| hash[key] = {} }
+ end
+
+ def register_uri(method, uri, options)
+ uri_map[normalize_uri(uri)][method] = [*[options]].flatten.collect do |option|
+ FakeWeb::Responder.new(method, uri, option, option[:times])
+ end
+ end
+
+ def registered_uri?(method, uri)
+ !responders_for(method, uri).empty?
+ end
+
+ def response_for(method, uri, &block)
+ responders = responders_for(method, uri)
+ return nil if responders.empty?
+
+ next_responder = responders.last
+ responders.each do |responder|
+ if responder.times and responder.times > 0
+ responder.times -= 1
+ next_responder = responder
+ break
+ end
+ end
+
+ next_responder.response(&block)
+ end
+
+ def register_passthrough_uri(uri)
+ self.passthrough_uri_map = {normalize_uri(uri) => {:any => true}}
+ end
+
+ def remove_passthrough_uri
+ self.passthrough_uri_map = {}
+ end
+
+ def passthrough_uri_matches?(uri)
+ uri = normalize_uri(uri)
+ uri_map_matches(passthrough_uri_map, :any, uri, URI) ||
+ uri_map_matches(passthrough_uri_map, :any, uri, Regexp)
+ end
+
+ private
+
+ def responders_for(method, uri)
+ uri = normalize_uri(uri)
+
+ uri_map_matches(uri_map, method, uri, URI) ||
+ uri_map_matches(uri_map, :any, uri, URI) ||
+ uri_map_matches(uri_map, method, uri, Regexp) ||
+ uri_map_matches(uri_map, :any, uri, Regexp) ||
+ []
+ end
+
+ def uri_map_matches(map, method, uri, type_to_check = URI)
+ uris_to_check = variations_of_uri_as_strings(uri)
+
+ matches = map.select { |registered_uri, method_hash|
+ registered_uri.is_a?(type_to_check) && method_hash.has_key?(method)
+ }.select { |registered_uri, method_hash|
+ if type_to_check == URI
+ uris_to_check.include?(registered_uri.to_s)
+ elsif type_to_check == Regexp
+ uris_to_check.any? { |u| u.match(registered_uri) }
+ end
+ }
+
+ if matches.size > 1
+ raise MultipleMatchingURIsError,
+ "More than one registered URI matched this request: #{method.to_s.upcase} #{uri}"
+ end
+
+ matches.map { |_, method_hash| method_hash[method] }.first
+ end
+
+
+ def variations_of_uri_as_strings(uri_object)
+ normalized_uri = normalize_uri(uri_object.dup)
+ normalized_uri_string = normalized_uri.to_s
+
+ variations = [normalized_uri_string]
+
+ # if the port is implied in the original, add a copy with an explicit port
+ if normalized_uri.default_port == normalized_uri.port
+ variations << normalized_uri_string.sub(
+ /#{Regexp.escape(normalized_uri.request_uri)}$/,
+ ":#{normalized_uri.port}#{normalized_uri.request_uri}")
+ end
+
+ variations
+ end
+
+ def normalize_uri(uri)
+ return uri if uri.is_a?(Regexp)
+ normalized_uri =
+ case uri
+ when URI then uri
+ when String
+ uri = 'http://' + uri unless uri.match('^https?://')
+ URI.parse(uri)
+ end
+ normalized_uri.query = sort_query_params(normalized_uri.query)
+ normalized_uri.normalize
+ end
+
+ def sort_query_params(query)
+ if query.nil? || query.empty?
+ nil
+ else
+ query.split('&').sort.join('&')
+ end
+ end
+
+ end
+end
diff --git a/vendor/gems/fakeweb-1.3.0/lib/fake_web/responder.rb b/vendor/gems/fakeweb-1.3.0/lib/fake_web/responder.rb
new file mode 100644
index 000000000..573fec3d4
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/lib/fake_web/responder.rb
@@ -0,0 +1,122 @@
+module FakeWeb
+ class Responder #:nodoc:
+
+ attr_accessor :method, :uri, :options, :times
+ KNOWN_OPTIONS = [:body, :exception, :response, :status].freeze
+
+ def initialize(method, uri, options, times)
+ self.method = method
+ self.uri = uri
+ self.options = options
+ self.times = times ? times : 1
+
+ if options.has_key?(:file) || options.has_key?(:string)
+ print_file_string_options_deprecation_warning
+ options[:body] = options.delete(:file) || options.delete(:string)
+ end
+ end
+
+ def response(&block)
+ if has_baked_response?
+ response = baked_response
+ else
+ code, msg = meta_information
+ response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
+ response.instance_variable_set(:@body, body)
+ headers_extracted_from_options.each do |name, value|
+ if value.respond_to?(:each)
+ value.each { |v| response.add_field(name, v) }
+ else
+ response[name] = value
+ end
+ end
+ end
+
+ response.instance_variable_set(:@read, true)
+ response.extend FakeWeb::Response
+
+ optionally_raise(response)
+
+ yield response if block_given?
+
+ response
+ end
+
+ private
+
+ def headers_extracted_from_options
+ options.reject {|name, _| KNOWN_OPTIONS.include?(name) }.map { |name, value|
+ [name.to_s.split("_").map { |segment| segment.capitalize }.join("-"), value]
+ }
+ end
+
+ def body
+ return '' if options[:body].nil?
+
+ options[:body] = options[:body].to_s if defined?(Pathname) && options[:body].is_a?(Pathname)
+
+ if !options[:body].include?("\0") && File.exists?(options[:body]) && !File.directory?(options[:body])
+ File.read(options[:body])
+ else
+ options[:body]
+ end
+ end
+
+ def baked_response
+ return options[:response] if options[:response].is_a?(Net::HTTPResponse)
+
+ if options[:response].is_a?(String) || (defined?(Pathname) && options[:response].is_a?(Pathname))
+ socket = Net::BufferedIO.new(options[:response].to_s)
+ r = Net::HTTPResponse.read_new(socket)
+
+ # Store the original transfer-encoding
+ saved_transfer_encoding = r.instance_eval {
+ @header['transfer-encoding'] if @header.key?('transfer-encoding')
+ }
+
+ # Read the body of response
+ r.instance_eval { @header['transfer-encoding'] = nil }
+ r.reading_body(socket, true) {}
+
+ # Delete the transfer-encoding key from r.@header if there wasn't one;
+ # otherwise, restore the saved_transfer_encoding
+ if saved_transfer_encoding.nil?
+ r.instance_eval { @header.delete('transfer-encoding') }
+ else
+ r.instance_eval { @header['transfer-encoding'] = saved_transfer_encoding }
+ end
+ r
+ else
+ raise StandardError, "Handler unimplemented for response #{options[:response]}"
+ end
+ end
+
+ def has_baked_response?
+ options.has_key?(:response)
+ end
+
+ def optionally_raise(response)
+ return unless options.has_key?(:exception)
+
+ case options[:exception].to_s
+ when "Net::HTTPError", "OpenURI::HTTPError"
+ raise options[:exception].new('Exception from FakeWeb', response)
+ else
+ raise options[:exception].new('Exception from FakeWeb')
+ end
+ end
+
+ def meta_information
+ options.has_key?(:status) ? options[:status] : [200, 'OK']
+ end
+
+ def print_file_string_options_deprecation_warning
+ which = options.has_key?(:file) ? :file : :string
+ $stderr.puts
+ $stderr.puts "Deprecation warning: FakeWeb's :#{which} option has been renamed to :body."
+ $stderr.puts "Just replace :#{which} with :body in your FakeWeb.register_uri calls."
+ $stderr.puts "Called at #{caller[6]}"
+ end
+
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/fakeweb-1.3.0/lib/fake_web/response.rb b/vendor/gems/fakeweb-1.3.0/lib/fake_web/response.rb
new file mode 100644
index 000000000..41ba2557b
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/lib/fake_web/response.rb
@@ -0,0 +1,10 @@
+module FakeWeb
+ module Response #:nodoc:
+
+ def read_body(*args, &block)
+ yield @body if block_given?
+ @body
+ end
+
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/fakeweb-1.3.0/lib/fake_web/stub_socket.rb b/vendor/gems/fakeweb-1.3.0/lib/fake_web/stub_socket.rb
new file mode 100644
index 000000000..008681ca6
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/lib/fake_web/stub_socket.rb
@@ -0,0 +1,15 @@
+module FakeWeb
+ class StubSocket #:nodoc:
+
+ def initialize(*args)
+ end
+
+ def closed?
+ @closed ||= true
+ end
+
+ def readuntil(*args)
+ end
+
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/fakeweb-1.3.0/lib/fake_web/utility.rb b/vendor/gems/fakeweb-1.3.0/lib/fake_web/utility.rb
new file mode 100644
index 000000000..bd5d7161c
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/lib/fake_web/utility.rb
@@ -0,0 +1,87 @@
+module FakeWeb
+ module Utility #:nodoc:
+
+ def self.decode_userinfo_from_header(header)
+ header.sub(/^Basic /, "").unpack("m").first
+ end
+
+ def self.encode_unsafe_chars_in_userinfo(userinfo)
+ unsafe_in_userinfo = /[^#{URI::REGEXP::PATTERN::UNRESERVED};&=+$,]|^(#{URI::REGEXP::PATTERN::ESCAPED})/
+ userinfo.split(":").map { |part| uri_escape(part, unsafe_in_userinfo) }.join(":")
+ end
+
+ def self.strip_default_port_from_uri(uri)
+ case uri
+ when %r{^http://} then uri.sub(%r{:80(/|$)}, '\1')
+ when %r{^https://} then uri.sub(%r{:443(/|$)}, '\1')
+ else uri
+ end
+ end
+
+ # Returns a string with a normalized version of a Net::HTTP request's URI.
+ def self.request_uri_as_string(net_http, request)
+ protocol = net_http.use_ssl? ? "https" : "http"
+
+ path = request.path
+ path = URI.parse(request.path).request_uri if request.path =~ /^http/
+
+ if request["authorization"] =~ /^Basic /
+ userinfo = FakeWeb::Utility.decode_userinfo_from_header(request["authorization"])
+ userinfo = FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) + "@"
+ else
+ userinfo = ""
+ end
+
+ uri = "#{protocol}://#{userinfo}#{net_http.address}:#{net_http.port}#{path}"
+ end
+
+ # Wrapper for URI escaping that switches between URI::Parser#escape and
+ # URI.escape for 1.9-compatibility
+ def self.uri_escape(*args)
+ if URI.const_defined?(:Parser)
+ URI::Parser.new.escape(*args)
+ else
+ URI.escape(*args)
+ end
+ end
+
+ def self.produce_side_effects_of_net_http_request(request, body)
+ request.set_body_internal(body)
+ request.content_length = request.body.length unless request.body.nil?
+ end
+
+ def self.puts_warning_for_net_http_around_advice_libs_if_needed
+ libs = {"Samuel" => defined?(Samuel)}
+ warnings = libs.select { |_, loaded| loaded }.map do |name, _|
+ <<-TEXT.gsub(/ {10}/, '')
+ \e[1mWarning: FakeWeb was loaded after #{name}\e[0m
+ * #{name}'s code is being ignored when a request is handled by FakeWeb,
+ because both libraries work by patching Net::HTTP.
+ * To fix this, just reorder your requires so that FakeWeb is before #{name}.
+ TEXT
+ end
+ $stderr.puts "\n" + warnings.join("\n") + "\n" if warnings.any?
+ end
+
+ def self.record_loaded_net_http_replacement_libs
+ libs = {"RightHttpConnection" => defined?(RightHttpConnection)}
+ @loaded_net_http_replacement_libs = libs.map { |name, loaded| name if loaded }.compact
+ end
+
+ def self.puts_warning_for_net_http_replacement_libs_if_needed
+ libs = {"RightHttpConnection" => defined?(RightHttpConnection)}
+ warnings = libs.select { |_, loaded| loaded }.
+ reject { |name, _| @loaded_net_http_replacement_libs.include?(name) }.
+ map do |name, _|
+ <<-TEXT.gsub(/ {10}/, '')
+ \e[1mWarning: #{name} was loaded after FakeWeb\e[0m
+ * FakeWeb's code is being ignored, because #{name} replaces parts of
+ Net::HTTP without deferring to other libraries. This will break Net::HTTP requests.
+ * To fix this, just reorder your requires so that #{name} is before FakeWeb.
+ TEXT
+ end
+ $stderr.puts "\n" + warnings.join("\n") + "\n" if warnings.any?
+ end
+
+ end
+end
diff --git a/vendor/gems/fakeweb-1.3.0/lib/fakeweb.rb b/vendor/gems/fakeweb-1.3.0/lib/fakeweb.rb
new file mode 100644
index 000000000..6982966bf
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/lib/fakeweb.rb
@@ -0,0 +1,2 @@
+# So you can require "fakeweb" instead of "fake_web"
+require "fake_web" \ No newline at end of file
diff --git a/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_from_curl b/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_from_curl
new file mode 100644
index 000000000..fe2fe3945
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_from_curl
@@ -0,0 +1,12 @@
+HTTP/1.1 200 OK
+Cache-Control: private, max-age=0
+Date: Sun, 01 Feb 2009 02:16:24 GMT
+Expires: -1
+Content-Type: text/html; charset=ISO-8859-1
+Set-Cookie: PREF=ID=a6d9b5f5a4056dfe:TM=1233454584:LM=1233454584:S=U9pSwSu4eQwOPenX; expires=Tue, 01-Feb-2011 02:16:24 GMT; path=/; domain=.google.com
+Server: gws
+Transfer-Encoding: chunked
+
+<html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"><title>Google</title><script>var _gjwl=location;function _gjuc(){var a=_gjwl.hash;if(a.indexOf("&q=")>0||a.indexOf("#q=")>=0){a=a.substring(1);if(a.indexOf("#")==-1){for(var c=0;c<a.length;){var d=c;if(a.charAt(d)=="&")++d;var b=a.indexOf("&",d);if(b==-1)b=a.length;var e=a.substring(d,b);if(e.indexOf("fp=")==0){a=a.substring(0,c)+a.substring(b,a.length);b=c}else if(e=="cad=h")return 0;c=b}_gjwl.href="search?"+a+"&cad=h";return 1}}return 0};
+window._gjuc && location.hash && _gjuc();</script><style>body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c;font-size:20px}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}#gbar{height:22px;padding-left:2px}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}#gbi,#gbs{background:#fff;left:0;position:absolute;top:24px;visibility:hidden;z-index:1000}#gbi{border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;z-index:1001}#guser{padding-bottom:7px !important}#gbar,#guser{font-size:13px;padding-top:1px !important}@media all{.gb1,.gb3{height:22px;margin-right:.73em;vertical-align:top}#gbar{float:left}}.gb2{display:block;padding:.2em .5em}a.gb1,a.gb2,a.gb3{color:#00c !important}.gb2,.gb3{text-decoration:none}a.gb2:hover{background:#36c;color:#fff !important}</style><script>window.google={kEI:"-AWFSZ6qFYuUswO9j5HIDQ",kEXPI:"17259,19547",kHL:"en"};
+google.y={};google.x=function(e,g){google.y[e.id]=[e,g];return false};window.gbar={};(function(){var b=window.gbar,f,h;b.qs=function(a){var c=window.encodeURIComponent&&(document.forms[0].q||"").value;if(c)a.href=a.href.replace(/([?&])q=[^&]*|$/,function(i,g){return(g||"&")+"q="+encodeURIComponent(c)})};function j(a,c){a.visibility=h?"hidden":"visible";a.left=c+"px"}b.tg=function(a){a=a||window.event;var c=0,i,g=window.navExtra,d=document.getElementById("gbi"),e=a.target||a.srcElement;a.cancelBubble=true;if(!f){f=document.createElement(Array.every||window.createPopup?"iframe":"div");f.frameBorder="0";f.src="#";d.parentNode.appendChild(f).id="gbs";if(g)for(i in g)d.insertBefore(g[i],d.firstChild).className="gb2";document.onclick=b.close}if(e.className!="gb3")e=e.parentNode;do c+=e.offsetLeft;while(e=e.offsetParent);j(d.style,c);f.style.width=d.offsetWidth+"px";f.style.height=d.offsetHeight+"px";j(f.style,c);h=!h};b.close=function(a){h&&b.tg(a)}})();</script></head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="document.f.q.focus();if(document.images)new Image().src='/images/nav_logo3.png'" topmargin=3 marginheight=3><div id=gbar><nobr><b class=gb1>Web</b> <a href="http://images.google.com/imghp?hl=en&tab=wi" onclick=gbar.qs(this) class=gb1>Images</a> <a href="http://maps.google.com/maps?hl=en&tab=wl" onclick=gbar.qs(this) class=gb1>Maps</a> <a href="http://news.google.com/nwshp?hl=en&tab=wn" onclick=gbar.qs(this) class=gb1>News</a> <a href="http://www.google.com/prdhp?hl=en&tab=wf" onclick=gbar.qs(this) class=gb1>Shopping</a> <a href="http://mail.google.com/mail/?hl=en&tab=wm" class=gb1>Gmail</a> <a href="http://www.google.com/intl/en/options/" onclick="this.blur();gbar.tg(event);return !1" class=gb3><u>more</u> <small>&#9660;</small></a><div id=gbi> <a href="http://video.google.com/?hl=en&tab=wv" onclick=gbar.qs(this) class=gb2>Video</a> <a href="http://groups.google.com/grphp?hl=en&tab=wg" onclick=gbar.qs(this) class=gb2>Groups</a> <a href="http://books.google.com/bkshp?hl=en&tab=wp" onclick=gbar.qs(this) class=gb2>Books</a> <a href="http://scholar.google.com/schhp?hl=en&tab=ws" onclick=gbar.qs(this) class=gb2>Scholar</a> <a href="http://finance.google.com/finance?hl=en&tab=we" onclick=gbar.qs(this) class=gb2>Finance</a> <a href="http://blogsearch.google.com/?hl=en&tab=wb" onclick=gbar.qs(this) class=gb2>Blogs</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.youtube.com/?hl=en&tab=w1" onclick=gbar.qs(this) class=gb2>YouTube</a> <a href="http://www.google.com/calendar/render?hl=en&tab=wc" class=gb2>Calendar</a> <a href="http://picasaweb.google.com/home?hl=en&tab=wq" onclick=gbar.qs(this) class=gb2>Photos</a> <a href="http://docs.google.com/?hl=en&tab=wo" class=gb2>Documents</a> <a href="http://www.google.com/reader/view/?hl=en&tab=wy" class=gb2>Reader</a> <a href="http://sites.google.com/?hl=en&tab=w3" class=gb2>Sites</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.google.com/intl/en/options/" class=gb2>even more &raquo;</a></div> </nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div><div align=right id=guser style="font-size:84%;padding:0 0 4px" width=100%><nobr><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.com/ig%3Fhl%3Den%26source%3Diglk&usg=AFQjCNFA18XPfgb7dKnXfKz7x7g1GDH1tg">iGoogle</a> | <a href="https://www.google.com/accounts/Login?continue=http://www.google.com/&hl=en">Sign in</a></nobr></div><center><br clear=all id=lgpd><img alt="Google" height=110 src="/intl/en_ALL/images/logo.gif" width=276><br><br><form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top><td width=25%>&nbsp;</td><td align=center nowrap><input name=hl type=hidden value=en><input type=hidden name=ie value="ISO-8859-1"><input autocomplete="off" maxlength=2048 name=q size=55 title="Google Search" value=""><br><input name=btnG type=submit value="Google Search"><input name=btnI type=submit value="I'm Feeling Lucky"></td><td nowrap width=25%><font size=-2>&nbsp;&nbsp;<a href=/advanced_search?hl=en>Advanced Search</a><br>&nbsp;&nbsp;<a href=/preferences?hl=en>Preferences</a><br>&nbsp;&nbsp;<a href=/language_tools?hl=en>Language Tools</a></font></td></tr></table></form><br><font size=-1>Share what you know. <a href="/aclk?sa=L&ai=CYhslHwSFSZH6LIHusAPEsc2eBfv77nqP3YC9CsHZnNkTEAEgwVRQypDftPn_____AWDJBqoECU_QbUVlfOdxZw&num=1&sig=AGiWqtwRgqw8y_kza6RGKxBrCstaXkDJ7A&q=http://knol.google.com">Write a Knol</a>.</font><br><br><br><font size=-1><a href="/intl/en/ads/">Advertising&nbsp;Programs</a> - <a href="/services/">Business Solutions</a> - <a href="/intl/en/about.html">About Google</a></font><p><font size=-2>&copy;2009 - <a href="/intl/en/privacy.html">Privacy</a></font></p></center></body><script>if(google.y)google.y.first=[];window.setTimeout(function(){var xjs=document.createElement('script');xjs.src='/extern_js/f/CgJlbhICdXMgACswCjgVLCswDjgELCswGDgDLA/L3N5xu59nDE.js';document.getElementsByTagName('head')[0].appendChild(xjs)},0);google.y.first.push(function(){google.ac.i(document.f,document.f.q,'','')})</script><script>function _gjp() {!(location.hash && _gjuc()) && setTimeout(_gjp, 500);}window._gjuc && _gjp();</script></html> \ No newline at end of file
diff --git a/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_with_transfer_encoding b/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_with_transfer_encoding
new file mode 100644
index 000000000..82025d36e
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_with_transfer_encoding
@@ -0,0 +1,17 @@
+HTTP/1.1 200 OK
+Cache-Control: private, max-age=0
+Date: Sun, 01 Feb 2009 01:54:36 GMT
+Expires: -1
+Content-Type: text/html; charset=ISO-8859-1
+Set-Cookie: PREF=ID=4320bcaa30d097de:TM=1233453276:LM=1233453276:S=Eio39bg_nIabTxzL; expires=Tue, 01-Feb-2011 01:54:36 GMT; path=/; domain=.google.com
+Server: gws
+Transfer-Encoding: chunked
+
+fef
+<html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"><title>Google</title><script>var _gjwl=location;function _gjuc(){var a=_gjwl.hash;if(a.indexOf("&q=")>0||a.indexOf("#q=")>=0){a=a.substring(1);if(a.indexOf("#")==-1){for(var c=0;c<a.length;){var d=c;if(a.charAt(d)=="&")++d;var b=a.indexOf("&",d);if(b==-1)b=a.length;var e=a.substring(d,b);if(e.indexOf("fp=")==0){a=a.substring(0,c)+a.substring(b,a.length);b=c}else if(e=="cad=h")return 0;c=b}_gjwl.href="search?"+a+"&cad=h";return 1}}return 0};
+window._gjuc && location.hash && _gjuc();</script><style>body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c;font-size:20px}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}#gbar{height:22px;padding-left:2px}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}#gbi,#gbs{background:#fff;left:0;position:absolute;top:24px;visibility:hidden;z-index:1000}#gbi{border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;z-index:1001}#guser{padding-bottom:7px !important}#gbar,#guser{font-size:13px;padding-top:1px !important}@media all{.gb1,.gb3{height:22px;margin-right:.73em;vertical-align:top}#gbar{float:left}}.gb2{display:block;padding:.2em .5em}a.gb1,a.gb2,a.gb3{color:#00c !important}.gb2,.gb3{text-decoration:none}a.gb2:hover{background:#36c;color:#fff !important}</style><script>window.google={kEI:"3ACFSYC6EKTcswOL4_nBDQ",kEXPI:"17259,19463",kHL:"en"};
+google.y={};google.x=function(e,g){google.y[e.id]=[e,g];return false};window.gbar={};(function(){var b=window.gbar,f,h;b.qs=function(a){var c=window.encodeURIComponent&&(document.forms[0].q||"").value;if(c)a.href=a.href.replace(/([?&])q=[^&]*|$/,function(i,g){return(g||"&")+"q="+encodeURIComponent(c)})};function j(a,c){a.visibility=h?"hidden":"visible";a.left=c+"px"}b.tg=function(a){a=a||window.event;var c=0,i,g=window.navExtra,d=document.getElementById("gbi"),e=a.target||a.srcElement;a.cancelBubble=true;if(!f){f=document.createElement(Array.every||window.createPopup?"iframe":"div");f.frameBorder="0";f.src="#";d.parentNode.appendChild(f).id="gbs";if(g)for(i in g)d.insertBefore(g[i],d.firstChild).className="gb2";document.onclick=b.close}if(e.className!="gb3")e=e.parentNode;do c+=e.offsetLeft;while(e=e.offsetParent);j(d.style,c);f.style.width=d.offsetWidth+"px";f.style.height=d.offsetHeight+"px";j(f.style,c);h=!h};b.close=function(a){h&&b.tg(a)}})();</script></head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="document.f.q.focus();if(document.images)new Image().src='/images/nav_logo3.png'" topmargin=3 marginheight=3><div id=gbar><nobr><b class=gb1>Web</b> <a href="http://images.google.com/imghp?hl=en&tab=wi" onclick=gbar.qs(this) class=gb1>Images</a> <a href="http://maps.google.com/maps?hl=en&tab=wl" onclick=gbar.qs(this) class=gb1>Maps</a> <a href="http://news.google.com/nwshp?hl=en&tab=wn" onclick=gbar.qs(this) class=gb1>News</a> <a href="http://www.google.com/prdhp?hl=en&tab=wf" onclick=gbar.qs(this) class=gb1>Shopping</a> <a href="http://mail.google.com/mail/?hl=en&tab=wm" class=gb1>Gmail</a> <a href="http://www.google.com/intl/en/options/" onclick="this.blur();gbar.tg(event);return !1" class=gb3><u>more</u> <small>&#9660;</small></a><div id=gbi> <a href="http://video.google.com/?hl=en&tab=wv" onclick=gbar.qs(this) class=gb2>Video</a> <a href="http://groups.google.com/grphp?hl=en&tab=wg" onclick=gbar.qs(this) class=gb2>Groups</a> <a href="http://books.google.com/bkshp?hl=en&tab=wp" onclick=gbar.qs(this) class=gb2>Books</a> <a href="http://scholar.google.com/schhp?hl=en&tab=ws" onclick=gbar.qs(this) class=gb2>Scholar</a> <a href="http://finance.google.com/finance?hl=en&tab=we" onclick=gbar.qs(this) class=gb2>Finance</a> <a href="http://blogsearch.google.com/?hl=en&tab=wb" onclick=gbar.qs(this) class=gb2>Blogs</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.youtube.com/?hl=en&tab=w1" onclick=gbar.qs(this) class=gb2>YouTube</a> <a href="http://www.google.com/calendar/render?hl=en&tab=wc" class=gb2>Calendar</a> <a href="http
+a27
+://picasaweb.google.com/home?hl=en&tab=wq" onclick=gbar.qs(this) class=gb2>Photos</a> <a href="http://docs.google.com/?hl=en&tab=wo" class=gb2>Documents</a> <a href="http://www.google.com/reader/view/?hl=en&tab=wy" class=gb2>Reader</a> <a href="http://sites.google.com/?hl=en&tab=w3" class=gb2>Sites</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.google.com/intl/en/options/" class=gb2>even more &raquo;</a></div> </nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div><div align=right id=guser style="font-size:84%;padding:0 0 4px" width=100%><nobr><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.com/ig%3Fhl%3Den%26source%3Diglk&usg=AFQjCNFA18XPfgb7dKnXfKz7x7g1GDH1tg">iGoogle</a> | <a href="https://www.google.com/accounts/Login?continue=http://www.google.com/&hl=en">Sign in</a></nobr></div><center><br clear=all id=lgpd><img alt="Google" height=110 src="/intl/en_ALL/images/logo.gif" width=276><br><br><form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top><td width=25%>&nbsp;</td><td align=center nowrap><input name=hl type=hidden value=en><input type=hidden name=ie value="ISO-8859-1"><input autocomplete="off" maxlength=2048 name=q size=55 title="Google Search" value=""><br><input name=btnG type=submit value="Google Search"><input name=btnI type=submit value="I'm Feeling Lucky"></td><td nowrap width=25%><font size=-2>&nbsp;&nbsp;<a href=/advanced_search?hl=en>Advanced Search</a><br>&nbsp;&nbsp;<a href=/preferences?hl=en>Preferences</a><br>&nbsp;&nbsp;<a href=/language_tools?hl=en>Language Tools</a></font></td></tr></table></form><br><font size=-1>Share what you know. <a href="/aclk?sa=L&ai=CFL7HzwCFSZCnCJSwsQPm842HB_v77nqP3YC9CsHZnNkTEAEgwVRQypDftPn_____AWDJBqoECU_Q1sTewQNSbw&num=1&sig=AGiWqtyz-UiOD3EpsSp4k3n8A7zooeg48g&q=http://knol.google.com">Write a Knol</a>.</font><br><br><br><font size=-1><a href="/intl/en/ads/">Advertising&nbsp;Programs</a> - <a href="/services/">Business Solutions</a> - <a href="/intl/en/about.html">About Google</a></font><p><font size=-2>&copy;2009 - <a href="/intl/en/privacy.html">Privacy</a></font></p></center></body><script>if(google.y)google.y.first=[];window.setTimeout(function(){var xjs=document.createElement('script');xjs.src='/extern_js/f/CgJlbhICdXMgACswCjgVLCswDjgELCswGDgDLA/L3N5xu59nDE.js';document.getElementsByTagName('head')[0].appendChild(xjs)},0);google.y.first.push(function(){google.ac.i(document.f,document.f.q,'','')})</script><script>function _gjp() {!(location.hash && _gjuc()) && setTimeout(_gjp, 500);}window._gjuc && _gjp();</script></html>
+0
+
diff --git a/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_without_transfer_encoding b/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_without_transfer_encoding
new file mode 100644
index 000000000..51433c990
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/fixtures/google_response_without_transfer_encoding
@@ -0,0 +1,11 @@
+HTTP/1.0 200 OK
+Cache-Control: private, max-age=0
+Date: Sun, 01 Feb 2009 01:55:33 GMT
+Expires: -1
+Content-Type: text/html; charset=ISO-8859-1
+Set-Cookie: PREF=ID=3c140c3eb4c4f516:TM=1233453333:LM=1233453333:S=OH7sElk2hOWkb9ot; expires=Tue, 01-Feb-2011 01:55:33 GMT; path=/; domain=.google.com
+Server: gws
+
+<html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"><title>Google</title><script>var _gjwl=location;function _gjuc(){var a=_gjwl.hash;if(a.indexOf("&q=")>0||a.indexOf("#q=")>=0){a=a.substring(1);if(a.indexOf("#")==-1){for(var c=0;c<a.length;){var d=c;if(a.charAt(d)=="&")++d;var b=a.indexOf("&",d);if(b==-1)b=a.length;var e=a.substring(d,b);if(e.indexOf("fp=")==0){a=a.substring(0,c)+a.substring(b,a.length);b=c}else if(e=="cad=h")return 0;c=b}_gjwl.href="search?"+a+"&cad=h";return 1}}return 0};
+window._gjuc && location.hash && _gjuc();</script><style>body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c;font-size:20px}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}#gbar{height:22px;padding-left:2px}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}#gbi,#gbs{background:#fff;left:0;position:absolute;top:24px;visibility:hidden;z-index:1000}#gbi{border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;z-index:1001}#guser{padding-bottom:7px !important}#gbar,#guser{font-size:13px;padding-top:1px !important}@media all{.gb1,.gb3{height:22px;margin-right:.73em;vertical-align:top}#gbar{float:left}}.gb2{display:block;padding:.2em .5em}a.gb1,a.gb2,a.gb3{color:#00c !important}.gb2,.gb3{text-decoration:none}a.gb2:hover{background:#36c;color:#fff !important}</style><script>window.google={kEI:"FQGFSY2rG5eSswOKpsHeDQ",kEXPI:"17259",kHL:"en"};
+google.y={};google.x=function(e,g){google.y[e.id]=[e,g];return false};window.gbar={};(function(){var b=window.gbar,f,h;b.qs=function(a){var c=window.encodeURIComponent&&(document.forms[0].q||"").value;if(c)a.href=a.href.replace(/([?&])q=[^&]*|$/,function(i,g){return(g||"&")+"q="+encodeURIComponent(c)})};function j(a,c){a.visibility=h?"hidden":"visible";a.left=c+"px"}b.tg=function(a){a=a||window.event;var c=0,i,g=window.navExtra,d=document.getElementById("gbi"),e=a.target||a.srcElement;a.cancelBubble=true;if(!f){f=document.createElement(Array.every||window.createPopup?"iframe":"div");f.frameBorder="0";f.src="#";d.parentNode.appendChild(f).id="gbs";if(g)for(i in g)d.insertBefore(g[i],d.firstChild).className="gb2";document.onclick=b.close}if(e.className!="gb3")e=e.parentNode;do c+=e.offsetLeft;while(e=e.offsetParent);j(d.style,c);f.style.width=d.offsetWidth+"px";f.style.height=d.offsetHeight+"px";j(f.style,c);h=!h};b.close=function(a){h&&b.tg(a)}})();</script></head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="document.f.q.focus();if(document.images)new Image().src='/images/nav_logo3.png'" topmargin=3 marginheight=3><div id=gbar><nobr><b class=gb1>Web</b> <a href="http://images.google.com/imghp?hl=en&tab=wi" onclick=gbar.qs(this) class=gb1>Images</a> <a href="http://maps.google.com/maps?hl=en&tab=wl" onclick=gbar.qs(this) class=gb1>Maps</a> <a href="http://news.google.com/nwshp?hl=en&tab=wn" onclick=gbar.qs(this) class=gb1>News</a> <a href="http://www.google.com/prdhp?hl=en&tab=wf" onclick=gbar.qs(this) class=gb1>Shopping</a> <a href="http://mail.google.com/mail/?hl=en&tab=wm" class=gb1>Gmail</a> <a href="http://www.google.com/intl/en/options/" onclick="this.blur();gbar.tg(event);return !1" class=gb3><u>more</u> <small>&#9660;</small></a><div id=gbi> <a href="http://video.google.com/?hl=en&tab=wv" onclick=gbar.qs(this) class=gb2>Video</a> <a href="http://groups.google.com/grphp?hl=en&tab=wg" onclick=gbar.qs(this) class=gb2>Groups</a> <a href="http://books.google.com/bkshp?hl=en&tab=wp" onclick=gbar.qs(this) class=gb2>Books</a> <a href="http://scholar.google.com/schhp?hl=en&tab=ws" onclick=gbar.qs(this) class=gb2>Scholar</a> <a href="http://finance.google.com/finance?hl=en&tab=we" onclick=gbar.qs(this) class=gb2>Finance</a> <a href="http://blogsearch.google.com/?hl=en&tab=wb" onclick=gbar.qs(this) class=gb2>Blogs</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.youtube.com/?hl=en&tab=w1" onclick=gbar.qs(this) class=gb2>YouTube</a> <a href="http://www.google.com/calendar/render?hl=en&tab=wc" class=gb2>Calendar</a> <a href="http://picasaweb.google.com/home?hl=en&tab=wq" onclick=gbar.qs(this) class=gb2>Photos</a> <a href="http://docs.google.com/?hl=en&tab=wo" class=gb2>Documents</a> <a href="http://www.google.com/reader/view/?hl=en&tab=wy" class=gb2>Reader</a> <a href="http://sites.google.com/?hl=en&tab=w3" class=gb2>Sites</a> <div class=gb2><div class=gbd></div></div> <a href="http://www.google.com/intl/en/options/" class=gb2>even more &raquo;</a></div> </nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div><div align=right id=guser style="font-size:84%;padding:0 0 4px" width=100%><nobr><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.com/ig%3Fhl%3Den%26source%3Diglk&usg=AFQjCNFA18XPfgb7dKnXfKz7x7g1GDH1tg">iGoogle</a> | <a href="https://www.google.com/accounts/Login?continue=http://www.google.com/&hl=en">Sign in</a></nobr></div><center><br clear=all id=lgpd><img alt="Google" height=110 src="/intl/en_ALL/images/logo.gif" width=276><br><br><form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top><td width=25%>&nbsp;</td><td align=center nowrap><input name=hl type=hidden value=en><input type=hidden name=ie value="ISO-8859-1"><input autocomplete="off" maxlength=2048 name=q size=55 title="Google Search" value=""><br><input name=btnG type=submit value="Google Search"><input name=btnI type=submit value="I'm Feeling Lucky"></td><td nowrap width=25%><font size=-2>&nbsp;&nbsp;<a href=/advanced_search?hl=en>Advanced Search</a><br>&nbsp;&nbsp;<a href=/preferences?hl=en>Preferences</a><br>&nbsp;&nbsp;<a href=/language_tools?hl=en>Language Tools</a></font></td></tr></table></form><br><font size=-1>Share what you know. <a href="/aclk?sa=L&ai=ClyBp_v-EScTWD4W2tQOxoqSkB_v77nqP3YC9CsHZnNkTEAEgwVRQypDftPn_____AWDJBqoECU_QphTjHaZ5QA&num=1&sig=AGiWqtwtBqZ-zra3DJd_1chQKhKGf7lMVg&q=http://knol.google.com">Write a Knol</a>.</font><br><br><br><font size=-1><a href="/intl/en/ads/">Advertising&nbsp;Programs</a> - <a href="/services/">Business Solutions</a> - <a href="/intl/en/about.html">About Google</a></font><p><font size=-2>&copy;2009 - <a href="/intl/en/privacy.html">Privacy</a></font></p></center></body><script>if(google.y)google.y.first=[];window.setTimeout(function(){var xjs=document.createElement('script');xjs.src='/extern_js/f/CgJlbhICdXMgACswCjgNLCswDjgELCswGDgDLA/oTKXc0xdkmY.js';document.getElementsByTagName('head')[0].appendChild(xjs)},0);google.y.first.push(function(){google.ac.i(document.f,document.f.q,'','')})</script><script>function _gjp() {!(location.hash && _gjuc()) && setTimeout(_gjp, 500);}window._gjuc && _gjp();</script></html> \ No newline at end of file
diff --git a/vendor/gems/fakeweb-1.3.0/test/fixtures/test_example.txt b/vendor/gems/fakeweb-1.3.0/test/fixtures/test_example.txt
new file mode 100644
index 000000000..6310da9df
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/fixtures/test_example.txt
@@ -0,0 +1 @@
+test example content \ No newline at end of file
diff --git a/vendor/gems/fakeweb-1.3.0/test/fixtures/test_txt_file b/vendor/gems/fakeweb-1.3.0/test/fixtures/test_txt_file
new file mode 100644
index 000000000..8cf2f17fe
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/fixtures/test_txt_file
@@ -0,0 +1,3 @@
+line 1
+line 2
+line 3 \ No newline at end of file
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_allow_net_connect.rb b/vendor/gems/fakeweb-1.3.0/test/test_allow_net_connect.rb
new file mode 100644
index 000000000..25f4d3d64
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_allow_net_connect.rb
@@ -0,0 +1,168 @@
+require 'test_helper'
+
+class TestFakeWebAllowNetConnect < Test::Unit::TestCase
+ def test_unregistered_requests_are_passed_through_when_allow_net_connect_is_true
+ FakeWeb.allow_net_connect = true
+ setup_expectations_for_real_apple_hot_news_request
+ Net::HTTP.get(URI.parse("http://images.apple.com/main/rss/hotnews/hotnews.rss"))
+ end
+
+ def test_raises_for_unregistered_requests_when_allow_net_connect_is_false
+ FakeWeb.allow_net_connect = false
+ assert_raise FakeWeb::NetConnectNotAllowedError do
+ Net::HTTP.get(URI.parse("http://example.com/"))
+ end
+ end
+
+ def test_unregistered_requests_are_passed_through_when_allow_net_connect_is_the_same_string
+ FakeWeb.allow_net_connect = "http://images.apple.com/main/rss/hotnews/hotnews.rss"
+ setup_expectations_for_real_apple_hot_news_request
+ Net::HTTP.get(URI.parse("http://images.apple.com/main/rss/hotnews/hotnews.rss"))
+ end
+
+ def test_unregistered_requests_are_passed_through_when_allow_net_connect_is_the_same_string_with_default_port
+ FakeWeb.allow_net_connect = "http://images.apple.com:80/main/rss/hotnews/hotnews.rss"
+ setup_expectations_for_real_apple_hot_news_request
+ Net::HTTP.get(URI.parse("http://images.apple.com/main/rss/hotnews/hotnews.rss"))
+ end
+
+ def test_unregistered_requests_are_passed_through_when_allow_net_connect_is_the_same_uri
+ FakeWeb.allow_net_connect = URI.parse("http://images.apple.com/main/rss/hotnews/hotnews.rss")
+ setup_expectations_for_real_apple_hot_news_request
+ Net::HTTP.get(URI.parse("http://images.apple.com/main/rss/hotnews/hotnews.rss"))
+ end
+
+ def test_unregistered_requests_are_passed_through_when_allow_net_connect_is_a_matching_regexp
+ FakeWeb.allow_net_connect = %r[^http://images\.apple\.com]
+ setup_expectations_for_real_apple_hot_news_request
+ Net::HTTP.get(URI.parse("http://images.apple.com/main/rss/hotnews/hotnews.rss"))
+ end
+
+ def test_raises_for_unregistered_requests_when_allow_net_connect_is_a_different_string
+ FakeWeb.allow_net_connect = "http://example.com"
+ assert_raise FakeWeb::NetConnectNotAllowedError do
+ Net::HTTP.get(URI.parse("http://example.com/path"))
+ end
+ end
+
+ def test_raises_for_unregistered_requests_when_allow_net_connect_is_a_different_uri
+ FakeWeb.allow_net_connect = URI.parse("http://example.com")
+ assert_raise FakeWeb::NetConnectNotAllowedError do
+ Net::HTTP.get(URI.parse("http://example.com/path"))
+ end
+ end
+
+ def test_raises_for_unregistered_requests_when_allow_net_connect_is_a_non_matching_regexp
+ FakeWeb.allow_net_connect = %r[example\.net]
+ assert_raise FakeWeb::NetConnectNotAllowedError do
+ Net::HTTP.get(URI.parse("http://example.com"))
+ end
+ end
+
+ def test_changing_allow_net_connect_from_string_to_false_corretly_removes_whitelist
+ FakeWeb.allow_net_connect = "http://example.com"
+ FakeWeb.allow_net_connect = false
+ assert_raise FakeWeb::NetConnectNotAllowedError do
+ Net::HTTP.get(URI.parse("http://example.com"))
+ end
+ end
+
+ def test_changing_allow_net_connect_from_true_to_string_corretly_limits_connections
+ FakeWeb.allow_net_connect = true
+ FakeWeb.allow_net_connect = "http://example.com"
+ assert_raise FakeWeb::NetConnectNotAllowedError do
+ Net::HTTP.get(URI.parse("http://example.net"))
+ end
+ end
+
+ def test_exception_message_includes_unregistered_request_method_and_uri_but_no_default_port
+ FakeWeb.allow_net_connect = false
+ exception = assert_raise FakeWeb::NetConnectNotAllowedError do
+ Net::HTTP.get(URI.parse("http://example.com/"))
+ end
+ assert exception.message.include?("GET http://example.com/")
+
+ exception = assert_raise FakeWeb::NetConnectNotAllowedError do
+ http = Net::HTTP.new("example.com", 443)
+ http.use_ssl = true
+ http.get("/")
+ end
+ assert exception.message.include?("GET https://example.com/")
+ end
+
+ def test_exception_message_includes_unregistered_request_port_when_not_default
+ FakeWeb.allow_net_connect = false
+ exception = assert_raise FakeWeb::NetConnectNotAllowedError do
+ Net::HTTP.start("example.com", 8000) { |http| http.get("/") }
+ end
+ assert exception.message.include?("GET http://example.com:8000/")
+
+ exception = assert_raise FakeWeb::NetConnectNotAllowedError do
+ http = Net::HTTP.new("example.com", 4433)
+ http.use_ssl = true
+ http.get("/")
+ end
+ assert exception.message.include?("GET https://example.com:4433/")
+ end
+
+ def test_exception_message_includes_unregistered_request_port_when_not_default_with_path
+ FakeWeb.allow_net_connect = false
+ exception = assert_raise FakeWeb::NetConnectNotAllowedError do
+ Net::HTTP.start("example.com", 8000) { |http| http.get("/test") }
+ end
+ assert exception.message.include?("GET http://example.com:8000/test")
+
+ exception = assert_raise FakeWeb::NetConnectNotAllowedError do
+ http = Net::HTTP.new("example.com", 4433)
+ http.use_ssl = true
+ http.get("/test")
+ end
+ assert exception.message.include?("GET https://example.com:4433/test")
+ end
+
+ def test_question_mark_method_returns_true_after_setting_allow_net_connect_to_true
+ FakeWeb.allow_net_connect = true
+ assert FakeWeb.allow_net_connect?
+ end
+
+ def test_question_mark_method_returns_false_after_setting_allow_net_connect_to_false
+ FakeWeb.allow_net_connect = false
+ assert !FakeWeb.allow_net_connect?
+ end
+
+ def test_question_mark_method_raises_with_no_argument_when_allow_net_connect_is_a_whitelist
+ FakeWeb.allow_net_connect = "http://example.com"
+ exception = assert_raise ArgumentError do
+ FakeWeb.allow_net_connect?
+ end
+ assert_equal "You must supply a URI to test", exception.message
+ end
+
+ def test_question_mark_method_returns_true_when_argument_is_same_uri_as_allow_net_connect_string
+ FakeWeb.allow_net_connect = "http://example.com"
+ assert FakeWeb.allow_net_connect?("http://example.com/")
+ end
+
+ def test_question_mark_method_returns_true_when_argument_matches_allow_net_connect_regexp
+ FakeWeb.allow_net_connect = %r[^https?://example.com/]
+ assert FakeWeb.allow_net_connect?("http://example.com/path")
+ assert FakeWeb.allow_net_connect?("https://example.com:443/")
+ end
+
+ def test_question_mark_method_returns_false_when_argument_does_not_match_allow_net_connect_regexp
+ FakeWeb.allow_net_connect = %r[^http://example.com/]
+ assert !FakeWeb.allow_net_connect?("http://example.com:8080")
+ end
+end
+
+
+class TestFakeWebAllowNetConnectWithCleanState < Test::Unit::TestCase
+ # Our test_helper.rb sets allow_net_connect = false in an inherited #setup
+ # method. Disable that here to test the default setting.
+ def setup; end
+ def teardown; end
+
+ def test_allow_net_connect_is_true_by_default
+ assert FakeWeb.allow_net_connect?
+ end
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_deprecations.rb b/vendor/gems/fakeweb-1.3.0/test/test_deprecations.rb
new file mode 100644
index 000000000..e5b8953c5
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_deprecations.rb
@@ -0,0 +1,54 @@
+require 'test_helper'
+
+class TestDeprecations < Test::Unit::TestCase
+
+ def test_register_uri_without_method_argument_prints_deprecation_warning
+ warning = capture_stderr do
+ FakeWeb.register_uri("http://example.com", :body => "test")
+ end
+ assert_match %r(deprecation warning: fakeweb)i, warning
+ end
+
+ def test_registered_uri_without_method_argument_prints_deprecation_warning
+ warning = capture_stderr do
+ FakeWeb.registered_uri?("http://example.com")
+ end
+ assert_match %r(deprecation warning: fakeweb)i, warning
+ end
+
+ def test_response_for_without_method_argument_prints_deprecation_warning
+ warning = capture_stderr do
+ FakeWeb.response_for("http://example.com")
+ end
+ assert_match %r(deprecation warning: fakeweb)i, warning
+ end
+
+ def test_register_uri_without_method_argument_prints_deprecation_warning_with_correct_caller
+ warning = capture_stderr do
+ FakeWeb.register_uri("http://example.com", :body => "test")
+ end
+ assert_match %r(Called at.*?test_deprecations\.rb)i, warning
+ end
+
+ def test_register_uri_with_string_option_prints_deprecation_warning
+ warning = capture_stderr do
+ FakeWeb.register_uri(:get, "http://example.com", :string => "test")
+ end
+ assert_match %r(deprecation warning: fakeweb's :string option)i, warning
+ end
+
+ def test_register_uri_with_file_option_prints_deprecation_warning
+ warning = capture_stderr do
+ FakeWeb.register_uri(:get, "http://example.com", :file => fixture_path("test_example.txt"))
+ end
+ assert_match %r(deprecation warning: fakeweb's :file option)i, warning
+ end
+
+ def test_register_uri_with_string_option_prints_deprecation_warning_with_correct_caller
+ warning = capture_stderr do
+ FakeWeb.register_uri(:get, "http://example.com", :string => "test")
+ end
+ assert_match %r(Called at.*?test_deprecations\.rb)i, warning
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_fake_authentication.rb b/vendor/gems/fakeweb-1.3.0/test/test_fake_authentication.rb
new file mode 100644
index 000000000..cff276441
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_fake_authentication.rb
@@ -0,0 +1,92 @@
+require 'test_helper'
+
+class TestFakeAuthentication < Test::Unit::TestCase
+
+ def test_register_uri_with_authentication
+ FakeWeb.register_uri(:get, 'http://user:pass@mock/test_example.txt', :body => "example")
+ assert FakeWeb.registered_uri?(:get, 'http://user:pass@mock/test_example.txt')
+ end
+
+ def test_register_uri_with_authentication_doesnt_trigger_without
+ FakeWeb.register_uri(:get, 'http://user:pass@mock/test_example.txt', :body => "example")
+ assert !FakeWeb.registered_uri?(:get, 'http://mock/test_example.txt')
+ end
+
+ def test_register_uri_with_authentication_doesnt_trigger_with_incorrect_credentials
+ FakeWeb.register_uri(:get, 'http://user:pass@mock/test_example.txt', :body => "example")
+ assert !FakeWeb.registered_uri?(:get, 'http://user:wrong@mock/test_example.txt')
+ end
+
+ def test_unauthenticated_request
+ FakeWeb.register_uri(:get, 'http://mock/auth.txt', :body => 'unauthorized')
+ http = Net::HTTP.new('mock', 80)
+ req = Net::HTTP::Get.new('/auth.txt')
+ assert_equal 'unauthorized', http.request(req).body
+ end
+
+ def test_authenticated_request
+ FakeWeb.register_uri(:get, 'http://user:pass@mock/auth.txt', :body => 'authorized')
+ http = Net::HTTP.new('mock',80)
+ req = Net::HTTP::Get.new('/auth.txt')
+ req.basic_auth 'user', 'pass'
+ assert_equal 'authorized', http.request(req).body
+ end
+
+ def test_authenticated_request_where_only_userinfo_differs
+ FakeWeb.register_uri(:get, 'http://user:pass@mock/auth.txt', :body => 'first user')
+ FakeWeb.register_uri(:get, 'http://user2:pass@mock/auth.txt', :body => 'second user')
+ http = Net::HTTP.new('mock')
+ req = Net::HTTP::Get.new('/auth.txt')
+ req.basic_auth 'user2', 'pass'
+ assert_equal 'second user', http.request(req).body
+ end
+
+ def test_basic_auth_support_is_transparent_to_oauth
+ FakeWeb.register_uri(:get, "http://sp.example.com/protected", :body => "secret")
+
+ # from http://oauth.net/core/1.0/#auth_header
+ auth_header = <<-HEADER
+ OAuth realm="http://sp.example.com/",
+ oauth_consumer_key="0685bd9184jfhq22",
+ oauth_token="ad180jjd733klru7",
+ oauth_signature_method="HMAC-SHA1",
+ oauth_signature="wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D",
+ oauth_timestamp="137131200",
+ oauth_nonce="4572616e48616d6d65724c61686176",
+ oauth_version="1.0"
+ HEADER
+ auth_header.gsub!(/\s+/, " ").strip!
+
+ http = Net::HTTP.new("sp.example.com", 80)
+ response = nil
+ http.start do |request|
+ response = request.get("/protected", {"authorization" => auth_header})
+ end
+ assert_equal "secret", response.body
+ end
+
+ def test_basic_auth_when_userinfo_contains_allowed_unencoded_characters
+ FakeWeb.register_uri(:get, "http://roses&hel1o,(+$):so;longs=@example.com", :body => "authorized")
+ http = Net::HTTP.new("example.com")
+ request = Net::HTTP::Get.new("/")
+ request.basic_auth("roses&hel1o,(+$)", "so;longs=")
+ assert_equal "authorized", http.request(request).body
+ end
+
+ def test_basic_auth_when_userinfo_contains_encoded_at_sign
+ FakeWeb.register_uri(:get, "http://user%40example.com:secret@example.com", :body => "authorized")
+ http = Net::HTTP.new("example.com")
+ request = Net::HTTP::Get.new("/")
+ request.basic_auth("user@example.com", "secret")
+ assert_equal "authorized", http.request(request).body
+ end
+
+ def test_basic_auth_when_userinfo_contains_allowed_encoded_characters
+ FakeWeb.register_uri(:get, "http://us%20er:sec%20%2F%2Fret%3F@example.com", :body => "authorized")
+ http = Net::HTTP.new("example.com")
+ request = Net::HTTP::Get.new("/")
+ request.basic_auth("us er", "sec //ret?")
+ assert_equal "authorized", http.request(request).body
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_fake_web.rb b/vendor/gems/fakeweb-1.3.0/test/test_fake_web.rb
new file mode 100644
index 000000000..c6e6b59eb
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_fake_web.rb
@@ -0,0 +1,590 @@
+require 'test_helper'
+
+class TestFakeWeb < Test::Unit::TestCase
+
+ def test_register_uri
+ FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => "example")
+ assert FakeWeb.registered_uri?(:get, 'http://mock/test_example.txt')
+ end
+
+ def test_register_uri_with_wrong_number_of_arguments
+ assert_raises ArgumentError do
+ FakeWeb.register_uri("http://example.com")
+ end
+ assert_raises ArgumentError do
+ FakeWeb.register_uri(:get, "http://example.com", "/example", :body => "example")
+ end
+ end
+
+ def test_registered_uri_with_wrong_number_of_arguments
+ assert_raises ArgumentError do
+ FakeWeb.registered_uri?
+ end
+ assert_raises ArgumentError do
+ FakeWeb.registered_uri?(:get, "http://example.com", "/example")
+ end
+ end
+
+ def test_response_for_with_wrong_number_of_arguments
+ assert_raises ArgumentError do
+ FakeWeb.response_for
+ end
+ assert_raises ArgumentError do
+ FakeWeb.response_for(:get, "http://example.com", "/example")
+ end
+ end
+
+ def test_register_uri_without_domain_name
+ assert_raises URI::InvalidURIError do
+ FakeWeb.register_uri(:get, 'test_example2.txt', fixture_path("test_example.txt"))
+ end
+ end
+
+ def test_register_uri_with_port_and_check_with_port
+ FakeWeb.register_uri(:get, 'http://example.com:3000/', :body => 'foo')
+ assert FakeWeb.registered_uri?(:get, 'http://example.com:3000/')
+ end
+
+ def test_register_uri_with_port_and_check_without_port
+ FakeWeb.register_uri(:get, 'http://example.com:3000/', :body => 'foo')
+ assert !FakeWeb.registered_uri?(:get, 'http://example.com/')
+ end
+
+ def test_register_uri_with_default_port_for_http_and_check_without_port
+ FakeWeb.register_uri(:get, 'http://example.com:80/', :body => 'foo')
+ assert FakeWeb.registered_uri?(:get, 'http://example.com/')
+ end
+
+ def test_register_uri_with_default_port_for_https_and_check_without_port
+ FakeWeb.register_uri(:get, 'https://example.com:443/', :body => 'foo')
+ assert FakeWeb.registered_uri?(:get, 'https://example.com/')
+ end
+
+ def test_register_uri_with_no_port_for_http_and_check_with_default_port
+ FakeWeb.register_uri(:get, 'http://example.com/', :body => 'foo')
+ assert FakeWeb.registered_uri?(:get, 'http://example.com:80/')
+ end
+
+ def test_register_uri_with_no_port_for_https_and_check_with_default_port
+ FakeWeb.register_uri(:get, 'https://example.com/', :body => 'foo')
+ assert FakeWeb.registered_uri?(:get, 'https://example.com:443/')
+ end
+
+ def test_register_uri_with_no_port_for_https_and_check_with_443_on_http
+ FakeWeb.register_uri(:get, 'https://example.com/', :body => 'foo')
+ assert !FakeWeb.registered_uri?(:get, 'http://example.com:443/')
+ end
+
+ def test_register_uri_with_no_port_for_http_and_check_with_80_on_https
+ FakeWeb.register_uri(:get, 'http://example.com/', :body => 'foo')
+ assert !FakeWeb.registered_uri?(:get, 'https://example.com:80/')
+ end
+
+ def test_register_uri_for_any_method_explicitly
+ FakeWeb.register_uri(:any, "http://example.com/rpc_endpoint", :body => "OK")
+ assert FakeWeb.registered_uri?(:get, "http://example.com/rpc_endpoint")
+ assert FakeWeb.registered_uri?(:post, "http://example.com/rpc_endpoint")
+ assert FakeWeb.registered_uri?(:put, "http://example.com/rpc_endpoint")
+ assert FakeWeb.registered_uri?(:delete, "http://example.com/rpc_endpoint")
+ assert FakeWeb.registered_uri?(:any, "http://example.com/rpc_endpoint")
+ capture_stderr do # silence deprecation warning
+ assert FakeWeb.registered_uri?("http://example.com/rpc_endpoint")
+ end
+ end
+
+ def test_register_uri_for_get_method_only
+ FakeWeb.register_uri(:get, "http://example.com/users", :body => "User list")
+ assert FakeWeb.registered_uri?(:get, "http://example.com/users")
+ assert !FakeWeb.registered_uri?(:post, "http://example.com/users")
+ assert !FakeWeb.registered_uri?(:put, "http://example.com/users")
+ assert !FakeWeb.registered_uri?(:delete, "http://example.com/users")
+ assert !FakeWeb.registered_uri?(:any, "http://example.com/users")
+ capture_stderr do # silence deprecation warning
+ assert !FakeWeb.registered_uri?("http://example.com/users")
+ end
+ end
+
+ def test_clean_registry_affects_registered_uri
+ FakeWeb.register_uri(:get, "http://example.com", :body => "registered")
+ assert FakeWeb.registered_uri?(:get, "http://example.com")
+ FakeWeb.clean_registry
+ assert !FakeWeb.registered_uri?(:get, "http://example.com")
+ end
+
+ def test_clean_registry_affects_net_http_requests
+ FakeWeb.register_uri(:get, "http://example.com", :body => "registered")
+ response = Net::HTTP.start("example.com") { |query| query.get("/") }
+ assert_equal "registered", response.body
+ FakeWeb.clean_registry
+ assert_raise FakeWeb::NetConnectNotAllowedError do
+ Net::HTTP.start("example.com") { |query| query.get("/") }
+ end
+ end
+
+ def test_response_for_with_registered_uri
+ FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt"))
+ assert_equal 'test example content', FakeWeb.response_for(:get, 'http://mock/test_example.txt').body
+ end
+
+ def test_response_for_with_unknown_uri
+ assert_nil FakeWeb.response_for(:get, 'http://example.com/')
+ end
+
+ def test_response_for_with_put_method
+ FakeWeb.register_uri(:put, "http://example.com", :body => "response")
+ assert_equal 'response', FakeWeb.response_for(:put, "http://example.com").body
+ end
+
+ def test_response_for_with_any_method_explicitly
+ FakeWeb.register_uri(:any, "http://example.com", :body => "response")
+ assert_equal 'response', FakeWeb.response_for(:get, "http://example.com").body
+ assert_equal 'response', FakeWeb.response_for(:any, "http://example.com").body
+ end
+
+ def test_content_for_registered_uri_with_port_and_request_with_port
+ FakeWeb.register_uri(:get, 'http://example.com:3000/', :body => 'test example content')
+ response = Net::HTTP.start('example.com', 3000) { |http| http.get('/') }
+ assert_equal 'test example content', response.body
+ end
+
+ def test_content_for_registered_uri_with_default_port_for_http_and_request_without_port
+ FakeWeb.register_uri(:get, 'http://example.com:80/', :body => 'test example content')
+ response = Net::HTTP.start('example.com') { |http| http.get('/') }
+ assert_equal 'test example content', response.body
+ end
+
+ def test_content_for_registered_uri_with_no_port_for_http_and_request_with_default_port
+ FakeWeb.register_uri(:get, 'http://example.com/', :body => 'test example content')
+ response = Net::HTTP.start('example.com', 80) { |http| http.get('/') }
+ assert_equal 'test example content', response.body
+ end
+
+ def test_content_for_registered_uri_with_default_port_for_https_and_request_with_default_port
+ FakeWeb.register_uri(:get, 'https://example.com:443/', :body => 'test example content')
+ http = Net::HTTP.new('example.com', 443)
+ http.use_ssl = true
+ response = http.get('/')
+ assert_equal 'test example content', response.body
+ end
+
+ def test_content_for_registered_uri_with_no_port_for_https_and_request_with_default_port
+ FakeWeb.register_uri(:get, 'https://example.com/', :body => 'test example content')
+ http = Net::HTTP.new('example.com', 443)
+ http.use_ssl = true
+ response = http.get('/')
+ assert_equal 'test example content', response.body
+ end
+
+ def test_content_for_registered_uris_with_ports_on_same_domain_and_request_without_port
+ FakeWeb.register_uri(:get, 'http://example.com:3000/', :body => 'port 3000')
+ FakeWeb.register_uri(:get, 'http://example.com/', :body => 'port 80')
+ response = Net::HTTP.start('example.com') { |http| http.get('/') }
+ assert_equal 'port 80', response.body
+ end
+
+ def test_content_for_registered_uris_with_ports_on_same_domain_and_request_with_port
+ FakeWeb.register_uri(:get, 'http://example.com:3000/', :body => 'port 3000')
+ FakeWeb.register_uri(:get, 'http://example.com/', :body => 'port 80')
+ response = Net::HTTP.start('example.com', 3000) { |http| http.get('/') }
+ assert_equal 'port 3000', response.body
+ end
+
+ def test_content_for_registered_uri_with_get_method_only
+ FakeWeb.allow_net_connect = false
+ FakeWeb.register_uri(:get, "http://example.com/", :body => "test example content")
+ http = Net::HTTP.new('example.com')
+ assert_equal 'test example content', http.get('/').body
+ assert_raises(FakeWeb::NetConnectNotAllowedError) { http.post('/', nil) }
+ assert_raises(FakeWeb::NetConnectNotAllowedError) { http.put('/', nil) }
+ assert_raises(FakeWeb::NetConnectNotAllowedError) { http.delete('/') }
+ end
+
+ def test_content_for_registered_uri_with_any_method_explicitly
+ FakeWeb.allow_net_connect = false
+ FakeWeb.register_uri(:any, "http://example.com/", :body => "test example content")
+ http = Net::HTTP.new('example.com')
+ assert_equal 'test example content', http.get('/').body
+ assert_equal 'test example content', http.post('/', nil).body
+ assert_equal 'test example content', http.put('/', nil).body
+ assert_equal 'test example content', http.delete('/').body
+ end
+
+ def test_content_for_registered_uri_with_any_method_implicitly
+ FakeWeb.allow_net_connect = false
+ capture_stderr do # silence deprecation warning
+ FakeWeb.register_uri("http://example.com/", :body => "test example content")
+ end
+
+ http = Net::HTTP.new('example.com')
+ assert_equal 'test example content', http.get('/').body
+ assert_equal 'test example content', http.post('/', nil).body
+ assert_equal 'test example content', http.put('/', nil).body
+ assert_equal 'test example content', http.delete('/').body
+ end
+
+ def test_mock_request_with_block
+ FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt"))
+ response = Net::HTTP.start('mock') { |http| http.get('/test_example.txt') }
+ assert_equal 'test example content', response.body
+ end
+
+ def test_request_with_registered_body_yields_the_response_body_to_a_request_block
+ FakeWeb.register_uri(:get, "http://example.com", :body => "content")
+ body = nil
+ Net::HTTP.start("example.com") do |http|
+ http.get("/") do |response_body|
+ body = response_body
+ end
+ end
+ assert_equal "content", body
+ end
+
+ def test_request_with_registered_response_yields_the_response_body_to_a_request_block
+ fake_response = Net::HTTPOK.new('1.1', '200', 'OK')
+ fake_response.instance_variable_set(:@body, "content")
+ FakeWeb.register_uri(:get, 'http://example.com', :response => fake_response)
+ body = nil
+ Net::HTTP.start("example.com") do |http|
+ http.get("/") do |response_body|
+ body = response_body
+ end
+ end
+ assert_equal "content", body
+ end
+
+ def test_mock_request_with_undocumented_full_uri_argument_style
+ FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt"))
+ response = Net::HTTP.start('mock') { |query| query.get('http://mock/test_example.txt') }
+ assert_equal 'test example content', response.body
+ end
+
+ def test_mock_request_with_undocumented_full_uri_argument_style_and_query
+ FakeWeb.register_uri(:get, 'http://mock/test_example.txt?a=b', :body => 'test query content')
+ response = Net::HTTP.start('mock') { |query| query.get('http://mock/test_example.txt?a=b') }
+ assert_equal 'test query content', response.body
+ end
+
+ def test_mock_post
+ FakeWeb.register_uri(:post, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt"))
+ response = Net::HTTP.start('mock') { |query| query.post('/test_example.txt', '') }
+ assert_equal 'test example content', response.body
+ end
+
+ def test_mock_post_with_string_as_registered_uri
+ FakeWeb.register_uri(:post, 'http://mock/test_string.txt', :body => 'foo')
+ response = Net::HTTP.start('mock') { |query| query.post('/test_string.txt', '') }
+ assert_equal 'foo', response.body
+ end
+
+ def test_mock_post_with_body_sets_the_request_body
+ FakeWeb.register_uri(:post, "http://example.com/posts", :status => [201, "Created"])
+ http = Net::HTTP.new("example.com")
+ request = Net::HTTP::Post.new("/posts")
+ http.request(request, "title=Test")
+ assert_equal "title=Test", request.body
+ assert_equal 10, request.content_length
+ end
+
+ def test_mock_post_with_body_using_other_syntax_sets_the_request_body
+ FakeWeb.register_uri(:post, "http://example.com/posts", :status => [201, "Created"])
+ http = Net::HTTP.new("example.com")
+ request = Net::HTTP::Post.new("/posts")
+ request.body = "title=Test"
+ http.request(request)
+ assert_equal "title=Test", request.body
+ assert_equal 10, request.content_length
+ end
+
+ def test_real_post_with_body_sets_the_request_body
+ FakeWeb.allow_net_connect = true
+ setup_expectations_for_real_apple_hot_news_request :method => "POST",
+ :path => "/posts", :request_body => "title=Test"
+ http = Net::HTTP.new("images.apple.com")
+ request = Net::HTTP::Post.new("/posts")
+ request["Content-Type"] = "application/x-www-form-urlencoded"
+ http.request(request, "title=Test")
+ assert_equal "title=Test", request.body
+ assert_equal 10, request.content_length
+ end
+
+ def test_mock_get_with_request_as_registered_uri
+ fake_response = Net::HTTPOK.new('1.1', '200', 'OK')
+ FakeWeb.register_uri(:get, 'http://mock/test_response', :response => fake_response)
+ response = Net::HTTP.start('mock') { |query| query.get('/test_response') }
+ assert_equal fake_response, response
+ end
+
+ def test_mock_get_with_request_from_file_as_registered_uri
+ FakeWeb.register_uri(:get, 'http://www.google.com/', :response => fixture_path("google_response_without_transfer_encoding"))
+ response = Net::HTTP.start('www.google.com') { |query| query.get('/') }
+ assert_equal '200', response.code
+ assert response.body.include?('<title>Google</title>')
+ end
+
+ def test_mock_post_with_request_from_file_as_registered_uri
+ FakeWeb.register_uri(:post, 'http://www.google.com/', :response => fixture_path("google_response_without_transfer_encoding"))
+ response = Net::HTTP.start('www.google.com') { |query| query.post('/', '') }
+ assert_equal "200", response.code
+ assert response.body.include?('<title>Google</title>')
+ end
+
+ def test_proxy_request
+ FakeWeb.register_uri(:get, 'http://www.example.com/', :body => "hello world")
+ FakeWeb.register_uri(:get, 'http://your.proxy.host/', :body => "lala")
+
+ response = nil
+ Net::HTTP::Proxy('your.proxy.host', 8080).start('www.example.com') do |http|
+ response = http.get('/')
+ end
+ assert_equal "hello world", response.body
+ end
+
+ def test_https_request
+ FakeWeb.register_uri(:get, 'https://www.example.com/', :body => "Hello World")
+ http = Net::HTTP.new('www.example.com', 443)
+ http.use_ssl = true
+ response = http.get('/')
+ assert_equal "Hello World", response.body
+ end
+
+ def test_register_unimplemented_response
+ FakeWeb.register_uri(:get, 'http://mock/unimplemented', :response => 1)
+ assert_raises StandardError do
+ Net::HTTP.start('mock') { |q| q.get('/unimplemented') }
+ end
+ end
+
+ def test_specifying_nil_for_body
+ FakeWeb.register_uri(:head, "http://example.com", :body => nil)
+ response = Net::HTTP.start("example.com") { |query| query.head("/") }
+ assert_equal "", response.body
+ end
+
+ def test_real_http_request
+ FakeWeb.allow_net_connect = true
+ setup_expectations_for_real_apple_hot_news_request
+
+ resp = nil
+ Net::HTTP.start('images.apple.com') do |query|
+ resp = query.get('/main/rss/hotnews/hotnews.rss')
+ end
+ assert resp.body.include?('Apple')
+ assert resp.body.include?('News')
+ end
+
+ def test_real_http_request_with_undocumented_full_uri_argument_style
+ FakeWeb.allow_net_connect = true
+ setup_expectations_for_real_apple_hot_news_request(:path => 'http://images.apple.com/main/rss/hotnews/hotnews.rss')
+
+ resp = nil
+ Net::HTTP.start('images.apple.com') do |query|
+ resp = query.get('http://images.apple.com/main/rss/hotnews/hotnews.rss')
+ end
+ assert resp.body.include?('Apple')
+ assert resp.body.include?('News')
+ end
+
+ def test_real_https_request
+ FakeWeb.allow_net_connect = true
+ setup_expectations_for_real_apple_hot_news_request(:port => 443)
+
+ http = Net::HTTP.new('images.apple.com', 443)
+ http.use_ssl = true
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE # silence certificate warning
+ response = http.get('/main/rss/hotnews/hotnews.rss')
+ assert response.body.include?('Apple')
+ assert response.body.include?('News')
+ end
+
+ def test_real_request_on_same_domain_as_mock
+ FakeWeb.allow_net_connect = true
+ setup_expectations_for_real_apple_hot_news_request
+
+ FakeWeb.register_uri(:get, 'http://images.apple.com/test_string.txt', :body => 'foo')
+
+ resp = nil
+ Net::HTTP.start('images.apple.com') do |query|
+ resp = query.get('/main/rss/hotnews/hotnews.rss')
+ end
+ assert resp.body.include?('Apple')
+ assert resp.body.include?('News')
+ end
+
+ def test_mock_request_on_real_domain
+ FakeWeb.register_uri(:get, 'http://images.apple.com/test_string.txt', :body => 'foo')
+ resp = nil
+ Net::HTTP.start('images.apple.com') do |query|
+ resp = query.get('/test_string.txt')
+ end
+ assert_equal 'foo', resp.body
+ end
+
+ def test_mock_post_that_raises_exception
+ FakeWeb.register_uri(:post, 'http://mock/raising_exception.txt', :exception => StandardError)
+ assert_raises(StandardError) do
+ Net::HTTP.start('mock') do |query|
+ query.post('/raising_exception.txt', 'some data')
+ end
+ end
+ end
+
+ def test_mock_post_that_raises_an_http_error
+ FakeWeb.register_uri(:post, 'http://mock/raising_exception.txt', :exception => Net::HTTPError)
+ assert_raises(Net::HTTPError) do
+ Net::HTTP.start('mock') do |query|
+ query.post('/raising_exception.txt', '')
+ end
+ end
+ end
+
+ def test_raising_an_exception_that_requires_an_argument_to_instantiate
+ FakeWeb.register_uri(:get, "http://example.com/timeout.txt", :exception => Timeout::Error)
+ assert_raises(Timeout::Error) do
+ Net::HTTP.get(URI.parse("http://example.com/timeout.txt"))
+ end
+ end
+
+ def test_mock_instance_syntax
+ FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt"))
+ response = nil
+ uri = URI.parse('http://mock/test_example.txt')
+ http = Net::HTTP.new(uri.host, uri.port)
+ response = http.start do
+ http.get(uri.path)
+ end
+
+ assert_equal 'test example content', response.body
+ end
+
+ def test_mock_via_nil_proxy
+ response = nil
+ proxy_address = nil
+ proxy_port = nil
+ FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt"))
+ uri = URI.parse('http://mock/test_example.txt')
+ http = Net::HTTP::Proxy(proxy_address, proxy_port).new(
+ uri.host, (uri.port or 80))
+ response = http.start do
+ http.get(uri.path)
+ end
+
+ assert_equal 'test example content', response.body
+ end
+
+ def test_response_type
+ FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => "test")
+ response = Net::HTTP.start('mock') { |http| http.get('/test_example.txt') }
+ assert_kind_of Net::HTTPSuccess, response
+ end
+
+ def test_mock_request_that_raises_an_http_error_with_a_specific_status
+ FakeWeb.register_uri(:get, 'http://mock/raising_exception.txt', :exception => Net::HTTPError, :status => ['404', 'Not Found'])
+ exception = assert_raises(Net::HTTPError) do
+ Net::HTTP.start('mock') { |http| http.get('/raising_exception.txt') }
+ end
+ assert_equal '404', exception.response.code
+ assert_equal 'Not Found', exception.response.msg
+ end
+
+ def test_mock_rotate_responses
+ FakeWeb.register_uri(:get, 'http://mock/multiple_test_example.txt',
+ [ {:body => fixture_path("test_example.txt"), :times => 2},
+ {:body => "thrice", :times => 3},
+ {:body => "ever_more"} ])
+
+ uri = URI.parse('http://mock/multiple_test_example.txt')
+ 2.times { assert_equal 'test example content', Net::HTTP.get(uri) }
+ 3.times { assert_equal 'thrice', Net::HTTP.get(uri) }
+ 4.times { assert_equal 'ever_more', Net::HTTP.get(uri) }
+ end
+
+ def test_mock_request_using_response_with_transfer_encoding_header_has_valid_transfer_encoding_header
+ FakeWeb.register_uri(:get, 'http://www.google.com/', :response => fixture_path("google_response_with_transfer_encoding"))
+ response = Net::HTTP.start('www.google.com') { |query| query.get('/') }
+ assert_not_nil response['transfer-encoding']
+ assert response['transfer-encoding'] == 'chunked'
+ end
+
+ def test_mock_request_using_response_without_transfer_encoding_header_does_not_have_a_transfer_encoding_header
+ FakeWeb.register_uri(:get, 'http://www.google.com/', :response => fixture_path("google_response_without_transfer_encoding"))
+ response = nil
+ response = Net::HTTP.start('www.google.com') { |query| query.get('/') }
+ assert !response.key?('transfer-encoding')
+ end
+
+ def test_mock_request_using_response_from_curl_has_original_transfer_encoding_header
+ FakeWeb.register_uri(:get, 'http://www.google.com/', :response => fixture_path("google_response_from_curl"))
+ response = Net::HTTP.start('www.google.com') { |query| query.get('/') }
+ assert_not_nil response['transfer-encoding']
+ assert response['transfer-encoding'] == 'chunked'
+ end
+
+ def test_txt_file_should_have_three_lines
+ FakeWeb.register_uri(:get, 'http://www.google.com/', :body => fixture_path("test_txt_file"))
+ response = Net::HTTP.start('www.google.com') { |query| query.get('/') }
+ assert response.body.split(/\n/).size == 3, "response has #{response.body.split(/\n/).size} lines should have 3"
+ end
+
+ def test_requiring_fakeweb_instead_of_fake_web
+ require "fakeweb"
+ end
+
+ def test_registering_with_string_containing_null_byte
+ # Regression test for File.exists? raising an ArgumentError ("string
+ # contains null byte") since :response first tries to find by filename.
+ # The string should be treated as a response body, instead, and an
+ # EOFError is raised when the byte is encountered.
+ FakeWeb.register_uri(:get, "http://example.com", :response => "test\0test")
+ assert_raise EOFError do
+ Net::HTTP.get(URI.parse("http://example.com"))
+ end
+
+ FakeWeb.register_uri(:get, "http://example.com", :body => "test\0test")
+ body = Net::HTTP.get(URI.parse("http://example.com"))
+ assert_equal "test\0test", body
+ end
+
+ def test_registering_with_string_that_is_a_directory_name
+ # Similar to above, but for Errno::EISDIR being raised since File.exists?
+ # returns true for directories
+ FakeWeb.register_uri(:get, "http://example.com", :response => File.dirname(__FILE__))
+ assert_raise EOFError do
+ body = Net::HTTP.get(URI.parse("http://example.com"))
+ end
+
+ FakeWeb.register_uri(:get, "http://example.com", :body => File.dirname(__FILE__))
+ body = Net::HTTP.get(URI.parse("http://example.com"))
+ assert_equal File.dirname(__FILE__), body
+ end
+
+ def test_registering_with_a_body_pointing_to_a_pathname
+ path = Pathname.new(fixture_path("test_example.txt"))
+ FakeWeb.register_uri(:get, "http://example.com", :body => path)
+ response = Net::HTTP.start("example.com") { |http| http.get("/") }
+ assert_equal "test example content", response.body
+ end
+
+ def test_registering_with_a_response_pointing_to_a_pathname
+ path = Pathname.new(fixture_path("google_response_without_transfer_encoding"))
+ FakeWeb.register_uri(:get, "http://google.com", :response => path)
+ response = Net::HTTP.start("google.com") { |http| http.get("/") }
+ assert response.body.include?("<title>Google</title>")
+ end
+
+ def test_http_version_from_string_response
+ FakeWeb.register_uri(:get, "http://example.com", :body => "example")
+ response = Net::HTTP.start("example.com") { |http| http.get("/") }
+ assert_equal "1.0", response.http_version
+ end
+
+ def test_http_version_from_file_response
+ FakeWeb.register_uri(:get, "http://example.com", :body => fixture_path("test_example.txt"))
+ response = Net::HTTP.start("example.com") { |http| http.get("/") }
+ assert_equal "1.0", response.http_version
+ end
+
+ def test_version
+ assert_equal "1.3.0", FakeWeb::VERSION
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_fake_web_open_uri.rb b/vendor/gems/fakeweb-1.3.0/test/test_fake_web_open_uri.rb
new file mode 100644
index 000000000..699a64762
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_fake_web_open_uri.rb
@@ -0,0 +1,58 @@
+require 'test_helper'
+
+class TestFakeWebOpenURI < Test::Unit::TestCase
+
+ def test_content_for_registered_uri
+ FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt"))
+ assert_equal 'test example content', FakeWeb.response_for(:get, 'http://mock/test_example.txt').body
+ end
+
+ def test_mock_open
+ FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt"))
+ assert_equal 'test example content', open('http://mock/test_example.txt').read
+ end
+
+ def test_mock_open_with_string_as_registered_uri
+ FakeWeb.register_uri(:get, 'http://mock/test_string.txt', :body => 'foo')
+ assert_equal 'foo', open('http://mock/test_string.txt').string
+ end
+
+ def test_real_open
+ FakeWeb.allow_net_connect = true
+ setup_expectations_for_real_apple_hot_news_request
+ resp = open('http://images.apple.com/main/rss/hotnews/hotnews.rss')
+ assert_equal "200", resp.status.first
+ body = resp.read
+ assert body.include?('Apple')
+ assert body.include?('News')
+ end
+
+ def test_mock_open_that_raises_exception
+ FakeWeb.register_uri(:get, 'http://mock/raising_exception.txt', :exception => StandardError)
+ assert_raises(StandardError) do
+ open('http://mock/raising_exception.txt')
+ end
+ end
+
+ def test_mock_open_that_raises_an_http_error
+ FakeWeb.register_uri(:get, 'http://mock/raising_exception.txt', :exception => OpenURI::HTTPError)
+ assert_raises(OpenURI::HTTPError) do
+ open('http://mock/raising_exception.txt')
+ end
+ end
+
+ def test_mock_open_that_raises_an_http_error_with_a_specific_status
+ FakeWeb.register_uri(:get, 'http://mock/raising_exception.txt', :exception => OpenURI::HTTPError, :status => ['123', 'jodel'])
+ exception = assert_raises(OpenURI::HTTPError) do
+ open('http://mock/raising_exception.txt')
+ end
+ assert_equal '123', exception.io.code
+ assert_equal 'jodel', exception.io.message
+ end
+
+ def test_mock_open_with_block
+ FakeWeb.register_uri(:get, 'http://mock/test_example.txt', :body => fixture_path("test_example.txt"))
+ body = open('http://mock/test_example.txt') { |f| f.readlines }
+ assert_equal 'test example content', body.first
+ end
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_helper.rb b/vendor/gems/fakeweb-1.3.0/test/test_helper.rb
new file mode 100644
index 000000000..b181391b1
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_helper.rb
@@ -0,0 +1,90 @@
+require 'test/unit'
+require 'open-uri'
+require 'pathname'
+require 'fake_web'
+require 'rbconfig'
+require 'rubygems'
+require 'mocha'
+
+
+# Give all tests a common setup and teardown that prevents shared state
+class Test::Unit::TestCase
+ alias setup_without_fakeweb setup
+ def setup
+ FakeWeb.clean_registry
+ @original_allow_net_connect = FakeWeb.allow_net_connect?
+ FakeWeb.allow_net_connect = false
+ end
+
+ alias teardown_without_fakeweb teardown
+ def teardown
+ FakeWeb.allow_net_connect = @original_allow_net_connect
+ end
+end
+
+
+module FakeWebTestHelper
+
+ def fixture_path(basename)
+ "test/fixtures/#{basename}"
+ end
+
+ def capture_stderr
+ $stderr = StringIO.new
+ yield
+ $stderr.rewind && $stderr.read
+ ensure
+ $stderr = STDERR
+ end
+
+ # The path to the current ruby interpreter. Adapted from Rake's FileUtils.
+ def ruby_path
+ ext = ((RbConfig::CONFIG['ruby_install_name'] =~ /\.(com|cmd|exe|bat|rb|sh)$/) ? "" : RbConfig::CONFIG['EXEEXT'])
+ File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'] + ext).sub(/.*\s.*/m, '"\&"')
+ end
+
+ # Sets several expectations (using Mocha) that a real HTTP request makes it
+ # past FakeWeb to the socket layer. You can use this when you need to check
+ # that a request isn't handled by FakeWeb.
+ def setup_expectations_for_real_request(options = {})
+ # Socket handling
+ if options[:port] == 443
+ socket = mock("SSLSocket")
+ OpenSSL::SSL::SSLSocket.expects(:===).with(socket).returns(true).at_least_once
+ OpenSSL::SSL::SSLSocket.expects(:new).with(socket, instance_of(OpenSSL::SSL::SSLContext)).returns(socket).at_least_once
+ socket.stubs(:sync_close=).returns(true)
+ socket.expects(:connect).with().at_least_once
+ else
+ socket = mock("TCPSocket")
+ Socket.expects(:===).with(socket).at_least_once.returns(true)
+ end
+
+ TCPSocket.expects(:open).with(options[:host], options[:port]).returns(socket).at_least_once
+ socket.stubs(:closed?).returns(false)
+ socket.stubs(:close).returns(true)
+
+ # Request/response handling
+ request_parts = ["#{options[:method]} #{options[:path]} HTTP/1.1", "Host: #{options[:host]}"]
+ socket.expects(:write).with(all_of(includes(request_parts[0]), includes(request_parts[1]))).returns(100)
+ if !options[:request_body].nil?
+ socket.expects(:write).with(options[:request_body]).returns(100)
+ end
+
+ read_method = RUBY_VERSION >= "1.9.2" ? :read_nonblock : :sysread
+ socket.expects(read_method).at_least_once.returns("HTTP/1.1 #{options[:response_code]} #{options[:response_message]}\nContent-Length: #{options[:response_body].length}\n\n#{options[:response_body]}").then.raises(EOFError)
+ end
+
+
+ # A helper that calls #setup_expectations_for_real_request for you, using
+ # defaults for our commonly used test request to images.apple.com.
+ def setup_expectations_for_real_apple_hot_news_request(options = {})
+ defaults = { :host => "images.apple.com", :port => 80, :method => "GET",
+ :path => "/main/rss/hotnews/hotnews.rss",
+ :response_code => 200, :response_message => "OK",
+ :response_body => "<title>Apple Hot News</title>" }
+ setup_expectations_for_real_request(defaults.merge(options))
+ end
+
+end
+
+Test::Unit::TestCase.send(:include, FakeWebTestHelper)
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_last_request.rb b/vendor/gems/fakeweb-1.3.0/test/test_last_request.rb
new file mode 100644
index 000000000..7868c83a1
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_last_request.rb
@@ -0,0 +1,29 @@
+require 'test_helper'
+
+class TestLastRequest < Test::Unit::TestCase
+
+ def test_last_request_returns_correct_net_http_request_class
+ FakeWeb.register_uri(:get, "http://example.com", :status => [200, "OK"])
+ Net::HTTP.start("example.com") { |http| http.get("/") }
+ assert_instance_of Net::HTTP::Get, FakeWeb.last_request
+ end
+
+ def test_last_request_has_correct_method_path_and_body_for_get
+ FakeWeb.register_uri(:get, "http://example.com", :status => [200, "OK"])
+ Net::HTTP.start("example.com") { |http| http.get("/") }
+ assert_equal "GET", FakeWeb.last_request.method
+ assert_equal "/", FakeWeb.last_request.path
+ assert_nil FakeWeb.last_request.body
+ assert_nil FakeWeb.last_request.content_length
+ end
+
+ def test_last_request_has_correct_method_path_and_body_for_post
+ FakeWeb.register_uri(:post, "http://example.com/posts", :status => [201, "Created"])
+ Net::HTTP.start("example.com") { |http| http.post("/posts", "title=Test") }
+ assert_equal "POST", FakeWeb.last_request.method
+ assert_equal "/posts", FakeWeb.last_request.path
+ assert_equal "title=Test", FakeWeb.last_request.body
+ assert_equal 10, FakeWeb.last_request.content_length
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_missing_open_uri.rb b/vendor/gems/fakeweb-1.3.0/test/test_missing_open_uri.rb
new file mode 100644
index 000000000..029ba1cab
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_missing_open_uri.rb
@@ -0,0 +1,25 @@
+require 'test_helper'
+
+class TestMissingOpenURI < Test::Unit::TestCase
+
+ def setup
+ super
+ @saved_open_uri = OpenURI
+ Object.send(:remove_const, :OpenURI)
+ end
+
+ def teardown
+ super
+ Object.const_set(:OpenURI, @saved_open_uri)
+ end
+
+
+ def test_register_using_exception_without_open_uri
+ # regression test for Responder needing OpenURI::HTTPError to be defined
+ FakeWeb.register_uri(:get, "http://example.com/", :exception => StandardError)
+ assert_raises(StandardError) do
+ Net::HTTP.start("example.com") { |http| http.get("/") }
+ end
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_missing_pathname.rb b/vendor/gems/fakeweb-1.3.0/test/test_missing_pathname.rb
new file mode 100644
index 000000000..ee16a0d7b
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_missing_pathname.rb
@@ -0,0 +1,37 @@
+require 'test_helper'
+
+class TestMissingPathname < Test::Unit::TestCase
+
+ def setup
+ super
+ @saved_pathname = Pathname
+ Object.send(:remove_const, :Pathname)
+ end
+
+ def teardown
+ super
+ Object.const_set(:Pathname, @saved_pathname)
+ end
+
+ # FakeWeb supports using Pathname objects where filenames are expected, but
+ # Pathname isn't required to use FakeWeb. Make sure everything still works
+ # when Pathname isn't in use.
+
+ def test_register_using_body_without_pathname
+ FakeWeb.register_uri(:get, "http://example.com/", :body => fixture_path("test_example.txt"))
+ Net::HTTP.start("example.com") { |http| http.get("/") }
+ end
+
+ def test_register_using_response_without_pathname
+ FakeWeb.register_uri(:get, "http://example.com/", :response => fixture_path("google_response_without_transfer_encoding"))
+ Net::HTTP.start("example.com") { |http| http.get("/") }
+ end
+
+ def test_register_using_unsupported_response_without_pathname
+ FakeWeb.register_uri(:get, "http://example.com/", :response => 1)
+ assert_raise StandardError do
+ Net::HTTP.start("example.com") { |http| http.get("/") }
+ end
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_other_net_http_libraries.rb b/vendor/gems/fakeweb-1.3.0/test/test_other_net_http_libraries.rb
new file mode 100644
index 000000000..af7e5e276
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_other_net_http_libraries.rb
@@ -0,0 +1,36 @@
+require 'test_helper'
+
+class TestOtherNetHttpLibraries < Test::Unit::TestCase
+
+ def capture_output_from_requiring(libs, additional_code = "")
+ requires = libs.map { |lib| "require '#{lib}'" }.join("; ")
+ fakeweb_dir = "#{File.dirname(__FILE__)}/../lib"
+ vendor_dirs = Dir["#{File.dirname(__FILE__)}/vendor/*/lib"]
+ load_path_opts = vendor_dirs.unshift(fakeweb_dir).map { |dir| "-I#{dir}" }.join(" ")
+
+ `#{ruby_path} #{load_path_opts} -e "#{requires}; #{additional_code}" 2>&1`
+ end
+
+ def test_requiring_samuel_before_fakeweb_prints_warning
+ output = capture_output_from_requiring %w(samuel fakeweb)
+ assert_match %r(Warning: FakeWeb was loaded after Samuel), output
+ end
+
+ def test_requiring_samuel_after_fakeweb_does_not_print_warning
+ output = capture_output_from_requiring %w(fakeweb samuel)
+ assert output.empty?
+ end
+
+ def test_requiring_right_http_connection_before_fakeweb_and_then_connecting_does_not_print_warning
+ additional_code = "Net::HTTP.start('example.com')"
+ output = capture_output_from_requiring %w(right_http_connection fakeweb), additional_code
+ assert output.empty?
+ end
+
+ def test_requiring_right_http_connection_after_fakeweb_and_then_connecting_prints_warning
+ additional_code = "Net::HTTP.start('example.com')"
+ output = capture_output_from_requiring %w(fakeweb right_http_connection), additional_code
+ assert_match %r(Warning: RightHttpConnection was loaded after FakeWeb), output
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_precedence.rb b/vendor/gems/fakeweb-1.3.0/test/test_precedence.rb
new file mode 100644
index 000000000..388b9f8a1
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_precedence.rb
@@ -0,0 +1,79 @@
+require 'test_helper'
+
+class TestPrecedence < Test::Unit::TestCase
+
+ def test_matching_get_strings_have_precedence_over_matching_get_regexes
+ FakeWeb.register_uri(:get, "http://example.com/test", :body => "string")
+ FakeWeb.register_uri(:get, %r|http://example\.com/test|, :body => "regex")
+ response = Net::HTTP.start("example.com") { |query| query.get('/test') }
+ assert_equal "string", response.body
+ end
+
+ def test_matching_any_strings_have_precedence_over_matching_any_regexes
+ FakeWeb.register_uri(:any, "http://example.com/test", :body => "string")
+ FakeWeb.register_uri(:any, %r|http://example\.com/test|, :body => "regex")
+ response = Net::HTTP.start("example.com") { |query| query.get('/test') }
+ assert_equal "string", response.body
+ end
+
+ def test_matching_get_strings_have_precedence_over_matching_any_strings
+ FakeWeb.register_uri(:get, "http://example.com/test", :body => "get method")
+ FakeWeb.register_uri(:any, "http://example.com/test", :body => "any method")
+ response = Net::HTTP.start("example.com") { |query| query.get('/test') }
+ assert_equal "get method", response.body
+
+ # registration order should not matter
+ FakeWeb.register_uri(:any, "http://example.com/test2", :body => "any method")
+ FakeWeb.register_uri(:get, "http://example.com/test2", :body => "get method")
+ response = Net::HTTP.start("example.com") { |query| query.get('/test2') }
+ assert_equal "get method", response.body
+ end
+
+ def test_matching_any_strings_have_precedence_over_matching_get_regexes
+ FakeWeb.register_uri(:any, "http://example.com/test", :body => "any string")
+ FakeWeb.register_uri(:get, %r|http://example\.com/test|, :body => "get regex")
+ response = Net::HTTP.start("example.com") { |query| query.get('/test') }
+ assert_equal "any string", response.body
+ end
+
+ def test_registered_strings_and_uris_are_equivalent_so_second_takes_precedence
+ FakeWeb.register_uri(:get, "http://example.com/test", :body => "string")
+ FakeWeb.register_uri(:get, URI.parse("http://example.com/test"), :body => "uri")
+ response = Net::HTTP.start("example.com") { |query| query.get('/test') }
+ assert_equal "uri", response.body
+
+ FakeWeb.register_uri(:get, URI.parse("http://example.com/test2"), :body => "uri")
+ FakeWeb.register_uri(:get, "http://example.com/test2", :body => "string")
+ response = Net::HTTP.start("example.com") { |query| query.get('/test2') }
+ assert_equal "string", response.body
+ end
+
+ def test_identical_registration_replaces_previous_registration
+ FakeWeb.register_uri(:get, "http://example.com/test", :body => "first")
+ FakeWeb.register_uri(:get, "http://example.com/test", :body => "second")
+ response = Net::HTTP.start("example.com") { |query| query.get('/test') }
+ assert_equal "second", response.body
+ end
+
+ def test_identical_registration_replaces_previous_registration_accounting_for_normalization
+ FakeWeb.register_uri(:get, "http://example.com/test?", :body => "first")
+ FakeWeb.register_uri(:get, "http://example.com:80/test", :body => "second")
+ response = Net::HTTP.start("example.com") { |query| query.get('/test') }
+ assert_equal "second", response.body
+ end
+
+ def test_identical_registration_replaces_previous_registration_accounting_for_query_params
+ FakeWeb.register_uri(:get, "http://example.com/test?a=1&b=2", :body => "first")
+ FakeWeb.register_uri(:get, "http://example.com/test?b=2&a=1", :body => "second")
+ response = Net::HTTP.start("example.com") { |query| query.get('/test?a=1&b=2') }
+ assert_equal "second", response.body
+ end
+
+ def test_identical_registration_replaces_previous_registration_with_regexes
+ FakeWeb.register_uri(:get, /test/, :body => "first")
+ FakeWeb.register_uri(:get, /test/, :body => "second")
+ response = Net::HTTP.start("example.com") { |query| query.get('/test') }
+ assert_equal "second", response.body
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_query_string.rb b/vendor/gems/fakeweb-1.3.0/test/test_query_string.rb
new file mode 100644
index 000000000..11a211848
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_query_string.rb
@@ -0,0 +1,45 @@
+require 'test_helper'
+
+class TestFakeWebQueryString < Test::Unit::TestCase
+
+ def test_register_uri_string_with_query_params
+ FakeWeb.register_uri(:get, 'http://example.com/?a=1&b=1', :body => 'foo')
+ assert FakeWeb.registered_uri?(:get, 'http://example.com/?a=1&b=1')
+
+ FakeWeb.register_uri(:post, URI.parse("http://example.org/?a=1&b=1"), :body => "foo")
+ assert FakeWeb.registered_uri?(:post, "http://example.org/?a=1&b=1")
+ end
+
+ def test_register_uri_with_query_params_and_check_in_different_order
+ FakeWeb.register_uri(:get, 'http://example.com/?a=1&b=1', :body => 'foo')
+ assert FakeWeb.registered_uri?(:get, 'http://example.com/?b=1&a=1')
+
+ FakeWeb.register_uri(:post, URI.parse('http://example.org/?a=1&b=1'), :body => 'foo')
+ assert FakeWeb.registered_uri?(:post, 'http://example.org/?b=1&a=1')
+ end
+
+ def test_registered_uri_gets_recognized_with_empty_query_params
+ FakeWeb.register_uri(:get, 'http://example.com/', :body => 'foo')
+ assert FakeWeb.registered_uri?(:get, 'http://example.com/?')
+
+ FakeWeb.register_uri(:post, URI.parse('http://example.org/'), :body => 'foo')
+ assert FakeWeb.registered_uri?(:post, 'http://example.org/?')
+ end
+
+ def test_register_uri_with_empty_query_params_and_check_with_none
+ FakeWeb.register_uri(:get, 'http://example.com/?', :body => 'foo')
+ assert FakeWeb.registered_uri?(:get, 'http://example.com/')
+
+ FakeWeb.register_uri(:post, URI.parse('http://example.org/?'), :body => 'foo')
+ assert FakeWeb.registered_uri?(:post, 'http://example.org/')
+ end
+
+ def test_registry_sort_query_params
+ assert_equal "a=1&b=2", FakeWeb::Registry.instance.send(:sort_query_params, "b=2&a=1")
+ end
+
+ def test_registry_sort_query_params_sorts_by_value_if_keys_collide
+ assert_equal "a=1&a=2&b=2", FakeWeb::Registry.instance.send(:sort_query_params, "a=2&b=2&a=1")
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_regexes.rb b/vendor/gems/fakeweb-1.3.0/test/test_regexes.rb
new file mode 100644
index 000000000..e2eba1db8
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_regexes.rb
@@ -0,0 +1,157 @@
+require 'test_helper'
+
+class TestRegexes < Test::Unit::TestCase
+
+ def test_registered_uri_with_pattern
+ FakeWeb.register_uri(:get, %r|http://example.com/test_example/\d+|, :body => "example")
+ assert FakeWeb.registered_uri?(:get, "http://example.com/test_example/25")
+ assert !FakeWeb.registered_uri?(:get, "http://example.com/test_example/abc")
+ end
+
+ def test_response_for_with_matching_registered_uri
+ FakeWeb.register_uri(:get, %r|http://www.google.com|, :body => "Welcome to Google!")
+ assert_equal "Welcome to Google!", FakeWeb.response_for(:get, "http://www.google.com").body
+ end
+
+ def test_response_for_with_matching_registered_uri_and_get_method_matching_to_any_method
+ FakeWeb.register_uri(:any, %r|http://www.example.com|, :body => "example")
+ assert_equal "example", FakeWeb.response_for(:get, "http://www.example.com").body
+ end
+
+ def test_registered_uri_with_authentication_and_pattern
+ FakeWeb.register_uri(:get, %r|http://user:pass@mock/example\.\w+|i, :body => "example")
+ assert FakeWeb.registered_uri?(:get, 'http://user:pass@mock/example.txt')
+ end
+
+ def test_registered_uri_with_authentication_and_pattern_handles_case_insensitivity
+ FakeWeb.register_uri(:get, %r|http://user:pass@mock/example\.\w+|i, :body => "example")
+ assert FakeWeb.registered_uri?(:get, 'http://uSeR:PAss@mock/example.txt')
+ end
+
+ def test_request_with_authentication_and_pattern_handles_case_insensitivity
+ FakeWeb.register_uri(:get, %r|http://user:pass@mock/example\.\w+|i, :body => "example")
+ http = Net::HTTP.new('mock', 80)
+ req = Net::HTTP::Get.new('/example.txt')
+ req.basic_auth 'uSeR', 'PAss'
+ assert_equal "example", http.request(req).body
+ end
+
+ def test_requesting_a_uri_that_matches_two_registered_regexes_raises_an_error
+ FakeWeb.register_uri(:get, %r|http://example\.com/|, :body => "first")
+ FakeWeb.register_uri(:get, %r|http://example\.com/a|, :body => "second")
+ assert_raise FakeWeb::MultipleMatchingURIsError do
+ Net::HTTP.start("example.com") { |query| query.get('/a') }
+ end
+ end
+
+ def test_requesting_a_uri_that_matches_two_registered_regexes_raises_an_error_including_request_info
+ FakeWeb.register_uri(:get, %r|http://example\.com/|, :body => "first")
+ FakeWeb.register_uri(:get, %r|http://example\.com/a|, :body => "second")
+ begin
+ Net::HTTP.start("example.com") { |query| query.get('/a') }
+ rescue FakeWeb::MultipleMatchingURIsError => exception
+ end
+ assert exception.message.include?("GET http://example.com/a")
+ end
+
+ def test_registry_does_not_find_using_mismatched_protocols_or_ports_when_registered_with_both
+ FakeWeb.register_uri(:get, %r|http://www.example.com:80|, :body => "example")
+ assert !FakeWeb.registered_uri?(:get, "https://www.example.com:80")
+ assert !FakeWeb.registered_uri?(:get, "http://www.example.com:443")
+ end
+
+ def test_registry_finds_using_non_default_port
+ FakeWeb.register_uri(:get, %r|example\.com:8080|, :body => "example")
+ assert FakeWeb.registered_uri?(:get, "http://www.example.com:8080/path")
+ assert FakeWeb.registered_uri?(:get, "https://www.example.com:8080/path")
+ end
+
+ def test_registry_finds_using_default_port_and_http_when_registered_with_explicit_port_80
+ FakeWeb.register_uri(:get, %r|example\.com:80|, :body => "example")
+ assert FakeWeb.registered_uri?(:get, "http://www.example.com/path")
+
+ # check other permutations, too
+ assert FakeWeb.registered_uri?(:get, "http://www.example.com:80/path")
+ assert FakeWeb.registered_uri?(:get, "http://www.example.com:8080/path")
+ assert FakeWeb.registered_uri?(:get, "https://www.example.com:80/path")
+ assert FakeWeb.registered_uri?(:get, "https://www.example.com:8080/path")
+ assert !FakeWeb.registered_uri?(:get, "https://www.example.com/path")
+ end
+
+ def test_registry_finds_using_default_port_and_https_when_registered_with_explicit_port_443
+ FakeWeb.register_uri(:get, %r|example\.com:443|, :body => "example")
+ assert FakeWeb.registered_uri?(:get, "https://www.example.com/path")
+
+ # check other permutations, too
+ assert FakeWeb.registered_uri?(:get, "https://www.example.com:443/path")
+ assert FakeWeb.registered_uri?(:get, "https://www.example.com:44321/path")
+ assert FakeWeb.registered_uri?(:get, "http://www.example.com:443/path")
+ assert FakeWeb.registered_uri?(:get, "http://www.example.com:44321/path")
+ assert !FakeWeb.registered_uri?(:get, "http://www.example.com/path")
+ end
+
+ def test_registry_only_finds_using_default_port_when_registered_without_if_protocol_matches
+ FakeWeb.register_uri(:get, %r|http://www.example.com/test|, :body => "example")
+ assert FakeWeb.registered_uri?(:get, "http://www.example.com:80/test")
+ assert !FakeWeb.registered_uri?(:get, "http://www.example.com:443/test")
+ assert !FakeWeb.registered_uri?(:get, "https://www.example.com:443/test")
+ FakeWeb.register_uri(:get, %r|https://www.example.org/test|, :body => "example")
+ assert FakeWeb.registered_uri?(:get, "https://www.example.org:443/test")
+ assert !FakeWeb.registered_uri?(:get, "https://www.example.org:80/test")
+ assert !FakeWeb.registered_uri?(:get, "http://www.example.org:80/test")
+ end
+
+ def test_registry_matches_using_mismatched_port_when_registered_without
+ FakeWeb.register_uri(:get, %r|http://www.example.com|, :body => "example")
+ assert FakeWeb.registered_uri?(:get, "http://www.example.com:80")
+ assert FakeWeb.registered_uri?(:get, "http://www.example.com:443")
+ assert FakeWeb.registered_uri?(:get, "http://www.example.com:12345")
+ assert !FakeWeb.registered_uri?(:get, "https://www.example.com:443")
+ assert !FakeWeb.registered_uri?(:get, "https://www.example.com")
+ end
+
+ def test_registry_matches_using_default_port_for_protocol_when_registered_without_protocol_or_port
+ FakeWeb.register_uri(:get, %r|www.example.com/home|, :body => "example")
+ assert FakeWeb.registered_uri?(:get, "http://www.example.com/home")
+ assert FakeWeb.registered_uri?(:get, "https://www.example.com/home")
+ assert FakeWeb.registered_uri?(:get, "http://www.example.com:80/home")
+ assert FakeWeb.registered_uri?(:get, "https://www.example.com:443/home")
+ assert !FakeWeb.registered_uri?(:get, "https://www.example.com:80/home")
+ assert !FakeWeb.registered_uri?(:get, "http://www.example.com:443/home")
+ end
+
+ def test_registry_matches_with_query_params
+ FakeWeb.register_uri(:get, %r[example.com/list\?(.*&|)important=1], :body => "example")
+ assert FakeWeb.registered_uri?(:get, "http://example.com/list?hash=123&important=1&unimportant=2")
+ assert FakeWeb.registered_uri?(:get, "http://example.com/list?hash=123&important=12&unimportant=2")
+ assert FakeWeb.registered_uri?(:get, "http://example.com/list?important=1&unimportant=2")
+ assert !FakeWeb.registered_uri?(:get, "http://example.com/list?important=2")
+ assert !FakeWeb.registered_uri?(:get, "http://example.com/list?important=2&unimportant=1")
+ assert !FakeWeb.registered_uri?(:get, "http://example.com/list?hash=123&important=2&unimportant=1")
+ assert !FakeWeb.registered_uri?(:get, "http://example.com/list?notimportant=1&unimportant=1")
+ end
+
+ def test_registry_does_not_match_when_regex_has_unsorted_query_params
+ FakeWeb.register_uri(:get, %r[example\.com/list\?b=2&a=1], :body => "example")
+ assert !FakeWeb.registered_uri?(:get, "http://example.com/list?b=2&a=1")
+ assert !FakeWeb.registered_uri?(:get, "http://example.com/list?a=1&b=2")
+ assert !FakeWeb.registered_uri?(:get, "https://example.com:443/list?b=2&a=1")
+ end
+
+ def test_registry_matches_when_regex_has_sorted_query_params
+ FakeWeb.register_uri(:get, %r[example\.com/list\?a=1&b=2], :body => "example")
+ assert FakeWeb.registered_uri?(:get, "http://example.com/list?b=2&a=1")
+ assert FakeWeb.registered_uri?(:get, "http://example.com/list?a=1&b=2")
+ assert FakeWeb.registered_uri?(:get, "https://example.com:443/list?b=2&a=1")
+ end
+
+ def test_registry_matches_quickly_with_lots_of_query_params
+ # regression test for code that tried to calculate the permutations of the
+ # query params, which hangs with a large number of params
+ FakeWeb.register_uri(:get, %r[example.com], :body => "example")
+ Timeout::timeout(1) do
+ FakeWeb.registered_uri?(:get, "http://example.com/?a=1&b=2&c=3&d=4&e=5&f=6&g=7&h=8")
+ end
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_response_headers.rb b/vendor/gems/fakeweb-1.3.0/test/test_response_headers.rb
new file mode 100644
index 000000000..45f3f5a99
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_response_headers.rb
@@ -0,0 +1,79 @@
+require 'test_helper'
+
+class TestResponseHeaders < Test::Unit::TestCase
+ def test_content_type_when_registering_with_string_and_content_type_header_as_symbol_option
+ FakeWeb.register_uri(:get, "http://example.com/users.json", :body => '[{"username": "chrisk"}]', :content_type => "application/json")
+ response = Net::HTTP.start("example.com") { |query| query.get("/users.json") }
+ assert_equal '[{"username": "chrisk"}]', response.body
+ assert_equal "application/json", response['Content-Type']
+ end
+
+ def test_content_type_when_registering_with_string_and_content_type_header_as_string_option
+ FakeWeb.register_uri(:get, "http://example.com/users.json", :body => '[{"username": "chrisk"}]', 'Content-Type' => "application/json")
+ response = Net::HTTP.start("example.com") { |query| query.get("/users.json") }
+ assert_equal "application/json", response['Content-Type']
+ end
+
+ def test_content_type_when_registering_with_string_only
+ FakeWeb.register_uri(:get, "http://example.com/users.json", :body => '[{"username": "chrisk"}]')
+ response = Net::HTTP.start("example.com") { |query| query.get("/users.json") }
+ assert_equal '[{"username": "chrisk"}]', response.body
+ assert_nil response['Content-Type']
+ end
+
+ def test_cookies_when_registering_with_file_and_set_cookie_header
+ FakeWeb.register_uri(:get, "http://example.com/", :body => fixture_path("test_example.txt"),
+ :set_cookie => "user_id=1; example=yes")
+ response = Net::HTTP.start("example.com") { |query| query.get("/") }
+ assert_equal "test example content", response.body
+ assert_equal "user_id=1; example=yes", response['Set-Cookie']
+ end
+
+ def test_multiple_set_cookie_headers
+ FakeWeb.register_uri(:get, "http://example.com", :set_cookie => ["user_id=1", "example=yes"])
+ response = Net::HTTP.start("example.com") { |query| query.get("/") }
+ assert_equal ["user_id=1", "example=yes"], response.get_fields('Set-Cookie')
+ assert_equal "user_id=1, example=yes", response['Set-Cookie']
+ end
+
+ def test_registering_with_baked_response_ignores_header_options
+ fake_response = Net::HTTPOK.new('1.1', '200', 'OK')
+ fake_response["Server"] = "Apache/1.3.27 (Unix)"
+ FakeWeb.register_uri(:get, "http://example.com/", :response => fake_response,
+ :server => "FakeWeb/1.2.3 (Ruby)")
+ response = Net::HTTP.start("example.com") { |query| query.get("/") }
+ assert_equal "200", response.code
+ assert_equal "OK", response.message
+ assert_equal "Apache/1.3.27 (Unix)", response["Server"]
+ end
+
+ def test_headers_are_rotated_when_registering_with_response_rotation
+ FakeWeb.register_uri(:get, "http://example.com",
+ [{:body => 'test1', :expires => "Thu, 14 Jun 2009 16:00:00 GMT",
+ :content_type => "text/plain"},
+ {:body => 'test2', :expires => "Thu, 14 Jun 2009 16:00:01 GMT"}])
+
+ first_response = second_response = nil
+ Net::HTTP.start("example.com") do |query|
+ first_response = query.get("/")
+ second_response = query.get("/")
+ end
+ assert_equal 'test1', first_response.body
+ assert_equal "Thu, 14 Jun 2009 16:00:00 GMT", first_response['Expires']
+ assert_equal "text/plain", first_response['Content-Type']
+ assert_equal 'test2', second_response.body
+ assert_equal "Thu, 14 Jun 2009 16:00:01 GMT", second_response['Expires']
+ assert_nil second_response['Content-Type']
+ end
+
+ def test_registering_with_status_option_and_response_headers
+ FakeWeb.register_uri(:get, "http://example.com", :status => ["301", "Moved Permanently"],
+ :location => "http://www.example.com")
+
+ response = Net::HTTP.start("example.com") { |query| query.get("/") }
+ assert_equal "301", response.code
+ assert_equal "Moved Permanently", response.message
+ assert_equal "http://www.example.com", response["Location"]
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_trailing_slashes.rb b/vendor/gems/fakeweb-1.3.0/test/test_trailing_slashes.rb
new file mode 100644
index 000000000..564d807dc
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_trailing_slashes.rb
@@ -0,0 +1,53 @@
+require 'test_helper'
+
+class TestFakeWebTrailingSlashes < Test::Unit::TestCase
+
+ def test_registering_root_without_slash_and_ask_predicate_method_with_slash
+ FakeWeb.register_uri(:get, "http://www.example.com", :body => "root")
+ assert FakeWeb.registered_uri?(:get, "http://www.example.com/")
+ end
+
+ def test_registering_root_without_slash_and_request
+ FakeWeb.register_uri(:get, "http://www.example.com", :body => "root")
+ response = Net::HTTP.start("www.example.com") { |query| query.get('/') }
+ assert_equal "root", response.body
+ end
+
+ def test_registering_root_with_slash_and_ask_predicate_method_without_slash
+ FakeWeb.register_uri(:get, "http://www.example.com/", :body => "root")
+ assert FakeWeb.registered_uri?(:get, "http://www.example.com")
+ end
+
+ def test_registering_root_with_slash_and_request
+ FakeWeb.register_uri(:get, "http://www.example.com/", :body => "root")
+ response = Net::HTTP.start("www.example.com") { |query| query.get('/') }
+ assert_equal "root", response.body
+ end
+
+ def test_registering_path_without_slash_and_ask_predicate_method_with_slash
+ FakeWeb.register_uri(:get, "http://www.example.com/users", :body => "User list")
+ assert !FakeWeb.registered_uri?(:get, "http://www.example.com/users/")
+ end
+
+ def test_registering_path_without_slash_and_request_with_slash
+ FakeWeb.allow_net_connect = false
+ FakeWeb.register_uri(:get, "http://www.example.com/users", :body => "User list")
+ assert_raise FakeWeb::NetConnectNotAllowedError do
+ response = Net::HTTP.start("www.example.com") { |query| query.get('/users/') }
+ end
+ end
+
+ def test_registering_path_with_slash_and_ask_predicate_method_without_slash
+ FakeWeb.register_uri(:get, "http://www.example.com/users/", :body => "User list")
+ assert !FakeWeb.registered_uri?(:get, "http://www.example.com/users")
+ end
+
+ def test_registering_path_with_slash_and_request_without_slash
+ FakeWeb.allow_net_connect = false
+ FakeWeb.register_uri(:get, "http://www.example.com/users/", :body => "User list")
+ assert_raise FakeWeb::NetConnectNotAllowedError do
+ response = Net::HTTP.start("www.example.com") { |query| query.get('/users') }
+ end
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/test_utility.rb b/vendor/gems/fakeweb-1.3.0/test/test_utility.rb
new file mode 100644
index 000000000..891de875b
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/test_utility.rb
@@ -0,0 +1,83 @@
+require 'test_helper'
+
+class TestUtility < Test::Unit::TestCase
+
+ def test_decode_userinfo_from_header_handles_basic_auth
+ authorization_header = "Basic dXNlcm5hbWU6c2VjcmV0"
+ userinfo = FakeWeb::Utility.decode_userinfo_from_header(authorization_header)
+ assert_equal "username:secret", userinfo
+ end
+
+ def test_encode_unsafe_chars_in_userinfo_does_not_encode_userinfo_safe_punctuation
+ userinfo = "user;&=+$,:secret"
+ assert_equal userinfo, FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo)
+ end
+
+ def test_encode_unsafe_chars_in_userinfo_does_not_encode_rfc_3986_unreserved_characters
+ userinfo = "-_.!~*'()abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:secret"
+ assert_equal userinfo, FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo)
+ end
+
+ def test_encode_unsafe_chars_in_userinfo_does_encode_other_characters
+ userinfo, safe_userinfo = 'us#rn@me:sec//ret?"', 'us%23rn%40me:sec%2F%2Fret%3F%22'
+ assert_equal safe_userinfo, FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo)
+ end
+
+ def test_strip_default_port_from_uri_strips_80_from_http_with_path
+ uri = "http://example.com:80/foo/bar"
+ stripped_uri = FakeWeb::Utility.strip_default_port_from_uri(uri)
+ assert_equal "http://example.com/foo/bar", stripped_uri
+ end
+
+ def test_strip_default_port_from_uri_strips_80_from_http_without_path
+ uri = "http://example.com:80"
+ stripped_uri = FakeWeb::Utility.strip_default_port_from_uri(uri)
+ assert_equal "http://example.com", stripped_uri
+ end
+
+ def test_strip_default_port_from_uri_strips_443_from_https_without_path
+ uri = "https://example.com:443"
+ stripped_uri = FakeWeb::Utility.strip_default_port_from_uri(uri)
+ assert_equal "https://example.com", stripped_uri
+ end
+
+ def test_strip_default_port_from_uri_strips_443_from_https
+ uri = "https://example.com:443/foo/bar"
+ stripped_uri = FakeWeb::Utility.strip_default_port_from_uri(uri)
+ assert_equal "https://example.com/foo/bar", stripped_uri
+ end
+
+ def test_strip_default_port_from_uri_does_not_strip_8080_from_http
+ uri = "http://example.com:8080/foo/bar"
+ assert_equal uri, FakeWeb::Utility.strip_default_port_from_uri(uri)
+ end
+
+ def test_strip_default_port_from_uri_does_not_strip_443_from_http
+ uri = "http://example.com:443/foo/bar"
+ assert_equal uri, FakeWeb::Utility.strip_default_port_from_uri(uri)
+ end
+
+ def test_strip_default_port_from_uri_does_not_strip_80_from_query_string
+ uri = "http://example.com/?a=:80&b=c"
+ assert_equal uri, FakeWeb::Utility.strip_default_port_from_uri(uri)
+ end
+
+ def test_strip_default_port_from_uri_does_not_modify_strings_that_do_not_start_with_http_or_https
+ uri = "httpz://example.com:80/"
+ assert_equal uri, FakeWeb::Utility.strip_default_port_from_uri(uri)
+ end
+
+ def test_request_uri_as_string
+ http = Net::HTTP.new("www.example.com", 80)
+ request = Net::HTTP::Get.new("/index.html")
+ expected = "http://www.example.com:80/index.html"
+ assert_equal expected, FakeWeb::Utility.request_uri_as_string(http, request)
+ end
+
+ def test_uri_escape_delegates_to_uri_parser_when_available
+ parsing_object = URI.const_defined?(:Parser) ? URI::Parser.any_instance : URI
+ parsing_object.expects(:escape).with("string", /unsafe/).returns("escaped")
+ assert_equal "escaped", FakeWeb::Utility.uri_escape("string", /unsafe/)
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/History.txt b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/History.txt
new file mode 100644
index 000000000..e06bcd0a2
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/History.txt
@@ -0,0 +1,59 @@
+== 0.0.1 2007-05-15
+* 1 major enhancement:
+ * Initial release
+
+== 0.1.2 2007-06-27
+
+* No major changes.
+
+== 0.1.3 2007-07-09
+
+* No change.
+
+== 0.1.4 2007-08-10
+
+* r1442, todd, 2007-08-07 15:45:24
+ * # 373, Add support in right_http_connection for bailing out to a block while
+ reading the HTTP response (to support GET streaming...)
+
+* r1411, todd, 2007-08-03 15:14:45
+ * # 373, Stream uploads (PUTs) if the source is a file, stream, or anything
+ read()-able
+
+== 1.1.0 2007-08-15
+Initial public release
+
+== 1.2.0 2007-10-05
+
+* r1867, konstantin, 2007-10-05 06:19:45
+ * # 220, (re)open connection to server if none exists or connection params
+ have changed
+
+== 1.2.1
+
+* r2648, konstantin, 01-24-08 11:12:00
+ * net_fix.rb moved from right_aws gem to fix the problem with uploading the streamable
+ objects to S3
+
+* r2764, konstantin, 02-08-08 00:05:00 +03:00
+ * "RightAws: incompatible Net::HTTP monkey-patch" exception is raised if our net_fix
+ patch was overriden (by attachment_fu for example, to avoid this load attachment_fu
+ before loading the right_http_connection gem).
+
+== 1.2.2
+
+* r3524, konstantin, 2008-04-17 11:35:42 +0400
+ * Fixed a problem with incorrect error handling (connection retries always failed).
+
+== 1.2.3
+
+- Added support for setting retry & timeout parameters in the constructor
+- Improve handling of data streams during upload: if there is a failure and a retry, reset
+ the seek pointer for the subsequent re-request
+
+== 1.2.4
+
+* r4984, konstantin, 2008-08-11 14:49:18 +0400
+ * fixed a bug: <NoMethodError: You have a nil object when you didn't expect it!
+ The error occurred while evaluating nil.body_stream>
+
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/Manifest.txt b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/Manifest.txt
new file mode 100644
index 000000000..20f193b21
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/Manifest.txt
@@ -0,0 +1,7 @@
+History.txt
+Manifest.txt
+README.txt
+Rakefile
+lib/net_fix.rb
+lib/right_http_connection.rb
+setup.rb
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/README.txt b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/README.txt
new file mode 100644
index 000000000..46c97e57a
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/README.txt
@@ -0,0 +1,54 @@
+RightScale::HttpConnection
+ by RightScale, Inc.
+ www.RightScale.com
+
+== DESCRIPTION:
+
+Rightscale::HttpConnection is a robust HTTP/S library. It implements a retry
+algorithm for low-level network errors.
+
+== FEATURES:
+
+- provides put/get streaming
+- does configurable retries on connect and read timeouts, DNS failures, etc.
+- HTTPS certificate checking
+
+== SYNOPSIS:
+
+
+== REQUIREMENTS:
+
+- 2/11/08: If you use RightScale::HttpConnection in conjunction with attachment_fu, the
+ HttpConnection gem must be included (using the require statement) AFTER
+ attachment_fu.
+ This is due to a conflict between the HttpConnection gem and another
+ gem required by attachment_fu.
+
+
+
+== INSTALL:
+
+sudo gem install right_http_connection
+
+== LICENSE:
+
+Copyright (c) 2007-2008 RightScale, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/Rakefile b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/Rakefile
new file mode 100644
index 000000000..0ae50977c
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/Rakefile
@@ -0,0 +1,103 @@
+require 'rubygems'
+require 'rake'
+require 'rake/clean'
+require 'rake/testtask'
+require 'rake/packagetask'
+require 'rake/gempackagetask'
+require 'rake/rdoctask'
+require 'rake/contrib/rubyforgepublisher'
+require 'fileutils'
+require 'hoe'
+include FileUtils
+require File.join(File.dirname(__FILE__), 'lib', 'right_http_connection')
+
+AUTHOR = 'RightScale' # can also be an array of Authors
+EMAIL = "rubygems@rightscale.com"
+DESCRIPTION = "RightScale's robust HTTP/S connection module"
+GEM_NAME = 'right_http_connection' # what ppl will type to install your gem
+RUBYFORGE_PROJECT = 'rightscale' # The unix name for your project
+HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
+DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
+
+NAME = "right_http_connection"
+REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
+VERS = RightHttpConnection::VERSION::STRING + (REV ? ".#{REV}" : "")
+CLEAN.include ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store']
+RDOC_OPTS = ['--quiet', '--title', 'right_http_connection documentation',
+ "--opname", "index.html",
+ "--line-numbers",
+ "--main", "README",
+ "--inline-source"]
+
+# Suppress Hoe's self-inclusion as a dependency for our Gem. This also keeps
+# Rake & rubyforge out of the dependency list. Users must manually install
+# these gems to run tests, etc.
+# TRB 2/19/09: also do this for the extra_dev_deps array present in newer hoes.
+# Older versions of RubyGems will try to install developer-dependencies as
+# required runtime dependencies....
+class Hoe
+ def extra_deps
+ @extra_deps.reject do |x|
+ Array(x).first == 'hoe'
+ end
+ end
+ def extra_dev_deps
+ @extra_dev_deps.reject do |x|
+ Array(x).first == 'hoe'
+ end
+ end
+end
+
+# Generate all the Rake tasks
+# Run 'rake -T' to see list of generated tasks (from gem root directory)
+hoe = Hoe.new(GEM_NAME, VERS) do |p|
+ p.author = AUTHOR
+ p.description = DESCRIPTION
+ p.email = EMAIL
+ p.summary = DESCRIPTION
+ p.url = HOMEPATH
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
+ p.test_globs = ["test/**/test_*.rb"]
+ p.clean_globs = CLEAN #An array of file patterns to delete on clean.
+ p.remote_rdoc_dir = "right_http_gem_doc"
+
+ # == Optional
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
+ #p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
+end
+
+
+desc 'Generate website files'
+task :website_generate do
+ Dir['website/**/*.txt'].each do |txt|
+ sh %{ ruby scripts/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
+ end
+end
+
+desc 'Upload website files to rubyforge'
+task :website_upload do
+ config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
+ host = "#{config["username"]}@rubyforge.org"
+ remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/"
+ # remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
+ local_dir = 'website'
+ sh %{rsync -av #{local_dir}/ #{host}:#{remote_dir}}
+end
+
+desc 'Generate and upload website files'
+task :website => [:website_generate, :website_upload]
+
+desc 'Release the website and new gem version'
+task :deploy => [:check_version, :website, :release]
+
+task :check_version do
+ unless ENV['VERSION']
+ puts 'Must pass a VERSION=x.y.z release version'
+ exit
+ end
+ unless ENV['VERSION'] == VERS
+ puts "Please update your version.rb to match the release version, currently #{VERS}"
+ exit
+ end
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/lib/net_fix.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/lib/net_fix.rb
new file mode 100644
index 000000000..ad54f8a2a
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/lib/net_fix.rb
@@ -0,0 +1,160 @@
+#
+# Copyright (c) 2008 RightScale Inc
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+#
+
+# Net::HTTP and Net::HTTPGenericRequest fixes to support 100-continue on
+# POST and PUT. The request must have 'expect' field set to '100-continue'.
+
+
+module Net
+
+ class BufferedIO #:nodoc:
+ # Monkey-patch Net::BufferedIO to read > 1024 bytes from the socket at a time
+
+ # Default size (in bytes) of the max read from a socket into the user space read buffers for socket IO
+ DEFAULT_SOCKET_READ_SIZE = 16*1024
+
+ @@socket_read_size = DEFAULT_SOCKET_READ_SIZE
+
+ def self.socket_read_size=(readsize)
+ if(readsize <= 0)
+ return
+ end
+ @@socket_read_size = readsize
+ end
+
+ def self.socket_read_size?()
+ @@socket_read_size
+ end
+
+ def rbuf_fill
+ timeout(@read_timeout) {
+ @rbuf << @io.sysread(@@socket_read_size)
+ }
+ end
+ end
+
+
+ #-- Net::HTTPGenericRequest --
+
+ class HTTPGenericRequest
+ # Monkey-patch Net::HTTPGenericRequest to read > 1024 bytes from the local data
+ # source at a time (used in streaming PUTs)
+
+ # Default size (in bytes) of the max read from a local source (File, String,
+ # etc.) to the user space write buffers for socket IO.
+ DEFAULT_LOCAL_READ_SIZE = 16*1024
+
+ @@local_read_size = DEFAULT_LOCAL_READ_SIZE
+
+ def self.local_read_size=(readsize)
+ if(readsize <= 0)
+ return
+ end
+ @@local_read_size = readsize
+ end
+
+ def self.local_read_size?()
+ @@local_read_size
+ end
+
+ def exec(sock, ver, path, send_only=nil) #:nodoc: internal use only
+ if @body
+ send_request_with_body sock, ver, path, @body, send_only
+ elsif @body_stream
+ send_request_with_body_stream sock, ver, path, @body_stream, send_only
+ else
+ write_header(sock, ver, path)
+ end
+ end
+
+ private
+
+ def send_request_with_body(sock, ver, path, body, send_only=nil)
+ self.content_length = body.length
+ delete 'Transfer-Encoding'
+ supply_default_content_type
+ write_header(sock, ver, path) unless send_only == :body
+ sock.write(body) unless send_only == :header
+ end
+
+ def send_request_with_body_stream(sock, ver, path, f, send_only=nil)
+ unless content_length() or chunked?
+ raise ArgumentError,
+ "Content-Length not given and Transfer-Encoding is not `chunked'"
+ end
+ supply_default_content_type
+ write_header(sock, ver, path) unless send_only == :body
+ unless send_only == :header
+ if chunked?
+ while s = f.read(@@local_read_size)
+ sock.write(sprintf("%x\r\n", s.length) << s << "\r\n")
+ end
+ sock.write "0\r\n\r\n"
+ else
+ while s = f.read(@@local_read_size)
+ sock.write s
+ end
+ end
+ end
+ end
+ end
+
+
+ #-- Net::HTTP --
+
+ class HTTP
+ def request(req, body = nil, &block) # :yield: +response+
+ unless started?
+ start {
+ req['connection'] ||= 'close'
+ return request(req, body, &block)
+ }
+ end
+ if proxy_user()
+ unless use_ssl?
+ req.proxy_basic_auth proxy_user(), proxy_pass()
+ end
+ end
+ # set body
+ req.set_body_internal body
+ begin_transport req
+ # if we expect 100-continue then send a header first
+ send_only = ((req.is_a?(Post)||req.is_a?(Put)) && (req['expect']=='100-continue')) ? :header : nil
+ req.exec @socket, @curr_http_version, edit_path(req.path), send_only
+ begin
+ res = HTTPResponse.read_new(@socket)
+ # if we expected 100-continue then send a body
+ if res.is_a?(HTTPContinue) && send_only && req['content-length'].to_i > 0
+ req.exec @socket, @curr_http_version, edit_path(req.path), :body
+ end
+ end while res.kind_of?(HTTPContinue)
+ res.reading_body(@socket, req.response_body_permitted?) {
+ yield res if block_given?
+ }
+ end_transport req, res
+ res
+ end
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb
new file mode 100644
index 000000000..0151ae685
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb
@@ -0,0 +1,435 @@
+#
+# Copyright (c) 2007-2008 RightScale Inc
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+require "net/https"
+require "uri"
+require "time"
+require "logger"
+
+$:.unshift(File.dirname(__FILE__))
+require "net_fix"
+
+
+module RightHttpConnection #:nodoc:
+ module VERSION #:nodoc:
+ MAJOR = 1
+ MINOR = 2
+ TINY = 4
+
+ STRING = [MAJOR, MINOR, TINY].join('.')
+ end
+end
+
+
+module Rightscale
+
+=begin rdoc
+HttpConnection maintains a persistent HTTP connection to a remote
+server. Each instance maintains its own unique connection to the
+HTTP server. HttpConnection makes a best effort to receive a proper
+HTTP response from the server, although it does not guarantee that
+this response contains a HTTP Success code.
+
+On low-level errors (TCP/IP errors) HttpConnection invokes a reconnect
+and retry algorithm. Note that although each HttpConnection object
+has its own connection to the HTTP server, error handling is shared
+across all connections to a server. For example, if there are three
+connections to www.somehttpserver.com, a timeout error on one of those
+connections will cause all three connections to break and reconnect.
+A connection will not break and reconnect, however, unless a request
+becomes active on it within a certain amount of time after the error
+(as specified by HTTP_CONNECTION_RETRY_DELAY). An idle connection will not
+break even if other connections to the same server experience errors.
+
+A HttpConnection will retry a request a certain number of times (as
+defined by HTTP_CONNNECTION_RETRY_COUNT). If all the retries fail,
+an exception is thrown and all HttpConnections associated with a
+server enter a probationary period defined by HTTP_CONNECTION_RETRY_DELAY.
+If the user makes a new request subsequent to entering probation,
+the request will fail immediately with the same exception thrown
+on probation entry. This is so that if the HTTP server has gone
+down, not every subsequent request must wait for a connect timeout
+before failing. After the probation period expires, the internal
+state of the HttpConnection is reset and subsequent requests have
+the full number of potential reconnects and retries available to
+them.
+=end
+
+ class HttpConnection
+
+ # Number of times to retry the request after encountering the first error
+ HTTP_CONNECTION_RETRY_COUNT = 3
+ # Throw a Timeout::Error if a connection isn't established within this number of seconds
+ HTTP_CONNECTION_OPEN_TIMEOUT = 5
+ # Throw a Timeout::Error if no data have been read on this connnection within this number of seconds
+ HTTP_CONNECTION_READ_TIMEOUT = 120
+ # Length of the post-error probationary period during which all requests will fail
+ HTTP_CONNECTION_RETRY_DELAY = 15
+
+ #--------------------
+ # class methods
+ #--------------------
+ #
+ @@params = {}
+ @@params[:http_connection_retry_count] = HTTP_CONNECTION_RETRY_COUNT
+ @@params[:http_connection_open_timeout] = HTTP_CONNECTION_OPEN_TIMEOUT
+ @@params[:http_connection_read_timeout] = HTTP_CONNECTION_READ_TIMEOUT
+ @@params[:http_connection_retry_delay] = HTTP_CONNECTION_RETRY_DELAY
+
+ # Query the global (class-level) parameters:
+ #
+ # :user_agent => 'www.HostName.com' # String to report as HTTP User agent
+ # :ca_file => 'path_to_file' # Path to a CA certification file in PEM format. The file can contain several CA certificates. If this parameter isn't set, HTTPS certs won't be verified.
+ # :logger => Logger object # If omitted, HttpConnection logs to STDOUT
+ # :exception => Exception to raise # The type of exception to raise
+ # # if a request repeatedly fails. RuntimeError is raised if this parameter is omitted.
+ # :http_connection_retry_count # by default == Rightscale::HttpConnection::HTTP_CONNECTION_RETRY_COUNT
+ # :http_connection_open_timeout # by default == Rightscale::HttpConnection::HTTP_CONNECTION_OPEN_TIMEOUT
+ # :http_connection_read_timeout # by default == Rightscale::HttpConnection::HTTP_CONNECTION_READ_TIMEOUT
+ # :http_connection_retry_delay # by default == Rightscale::HttpConnection::HTTP_CONNECTION_RETRY_DELAY
+ def self.params
+ @@params
+ end
+
+ # Set the global (class-level) parameters
+ def self.params=(params)
+ @@params = params
+ end
+
+ #------------------
+ # instance methods
+ #------------------
+ attr_accessor :http
+ attr_accessor :server
+ attr_accessor :params # see @@params
+ attr_accessor :logger
+
+ # Params hash:
+ # :user_agent => 'www.HostName.com' # String to report as HTTP User agent
+ # :ca_file => 'path_to_file' # A path of a CA certification file in PEM format. The file can contain several CA certificates.
+ # :logger => Logger object # If omitted, HttpConnection logs to STDOUT
+ # :exception => Exception to raise # The type of exception to raise if a request repeatedly fails. RuntimeError is raised if this parameter is omitted.
+ # :http_connection_retry_count # by default == Rightscale::HttpConnection.params[:http_connection_retry_count]
+ # :http_connection_open_timeout # by default == Rightscale::HttpConnection.params[:http_connection_open_timeout]
+ # :http_connection_read_timeout # by default == Rightscale::HttpConnection.params[:http_connection_read_timeout]
+ # :http_connection_retry_delay # by default == Rightscale::HttpConnection.params[:http_connection_retry_delay]
+ #
+ def initialize(params={})
+ @params = params
+ @params[:http_connection_retry_count] ||= @@params[:http_connection_retry_count]
+ @params[:http_connection_open_timeout] ||= @@params[:http_connection_open_timeout]
+ @params[:http_connection_read_timeout] ||= @@params[:http_connection_read_timeout]
+ @params[:http_connection_retry_delay] ||= @@params[:http_connection_retry_delay]
+ @http = nil
+ @server = nil
+ @logger = get_param(:logger) ||
+ (RAILS_DEFAULT_LOGGER if defined?(RAILS_DEFAULT_LOGGER)) ||
+ Logger.new(STDOUT)
+ end
+
+ def get_param(name)
+ @params[name] || @@params[name]
+ end
+
+ # Query for the maximum size (in bytes) of a single read from the underlying
+ # socket. For bulk transfer, especially over fast links, this is value is
+ # critical to performance.
+ def socket_read_size?
+ Net::BufferedIO.socket_read_size?
+ end
+
+ # Set the maximum size (in bytes) of a single read from the underlying
+ # socket. For bulk transfer, especially over fast links, this is value is
+ # critical to performance.
+ def socket_read_size=(newsize)
+ Net::BufferedIO.socket_read_size=(newsize)
+ end
+
+ # Query for the maximum size (in bytes) of a single read from local data
+ # sources like files. This is important, for example, in a streaming PUT of a
+ # large buffer.
+ def local_read_size?
+ Net::HTTPGenericRequest.local_read_size?
+ end
+
+ # Set the maximum size (in bytes) of a single read from local data
+ # sources like files. This can be used to tune the performance of, for example, a streaming PUT of a
+ # large buffer.
+ def local_read_size=(newsize)
+ Net::HTTPGenericRequest.local_read_size=(newsize)
+ end
+
+ private
+ #--------------
+ # Retry state - Keep track of errors on a per-server basis
+ #--------------
+ @@state = {} # retry state indexed by server: consecutive error count, error time, and error
+ @@eof = {}
+
+ # number of consecutive errors seen for server, 0 all is ok
+ def error_count
+ @@state[@server] ? @@state[@server][:count] : 0
+ end
+
+ # time of last error for server, nil if all is ok
+ def error_time
+ @@state[@server] && @@state[@server][:time]
+ end
+
+ # message for last error for server, "" if all is ok
+ def error_message
+ @@state[@server] ? @@state[@server][:message] : ""
+ end
+
+ # add an error for a server
+ def error_add(message)
+ @@state[@server] = { :count => error_count+1, :time => Time.now, :message => message }
+ end
+
+ # reset the error state for a server (i.e. a request succeeded)
+ def error_reset
+ @@state.delete(@server)
+ end
+
+ # Error message stuff...
+ def banana_message
+ return "#{@server} temporarily unavailable: (#{error_message})"
+ end
+
+ def err_header
+ return "#{self.class.name} :"
+ end
+
+ # Adds new EOF timestamp.
+ # Returns the number of seconds to wait before new conection retry:
+ # 0.5, 1, 2, 4, 8
+ def add_eof
+ (@@eof[@server] ||= []).unshift Time.now
+ 0.25 * 2 ** @@eof[@server].size
+ end
+
+ # Returns first EOF timestamp or nul if have no EOFs being tracked.
+ def eof_time
+ @@eof[@server] && @@eof[@server].last
+ end
+
+ # Returns true if we are receiving EOFs during last @params[:http_connection_retry_delay] seconds
+ # and there were no successful response from server
+ def raise_on_eof_exception?
+ @@eof[@server].blank? ? false : ( (Time.now.to_i-@params[:http_connection_retry_delay]) > @@eof[@server].last.to_i )
+ end
+
+ # Reset a list of EOFs for this server.
+ # This is being called when we have got an successful response from server.
+ def eof_reset
+ @@eof.delete(@server)
+ end
+
+ # Detects if an object is 'streamable' - can we read from it, and can we know the size?
+ def setup_streaming(request)
+ if(request.body && request.body.respond_to?(:read))
+ body = request.body
+ request.content_length = body.respond_to?(:lstat) ? body.lstat.size : body.size
+ request.body_stream = request.body
+ true
+ end
+ end
+
+ def get_fileptr_offset(request_params)
+ request_params[:request].body.pos
+ rescue Exception => e
+ # Probably caught this because the body doesn't support the pos() method, like if it is a socket.
+ # Just return 0 and get on with life.
+ 0
+ end
+
+ def reset_fileptr_offset(request, offset = 0)
+ if(request.body_stream && request.body_stream.respond_to?(:pos))
+ begin
+ request.body_stream.pos = offset
+ rescue Exception => e
+ @logger.warn("Failed file pointer reset; aborting HTTP retries." +
+ " -- #{err_header} #{e.inspect}")
+ raise e
+ end
+ end
+ end
+
+ # Start a fresh connection. The object closes any existing connection and
+ # opens a new one.
+ def start(request_params)
+ # close the previous if exists
+ finish
+ # create new connection
+ @server = request_params[:server]
+ @port = request_params[:port]
+ @protocol = request_params[:protocol]
+
+ @logger.info("Opening new #{@protocol.upcase} connection to #@server:#@port")
+ @http = Net::HTTP.new(@server, @port)
+ @http.open_timeout = @params[:http_connection_open_timeout]
+ @http.read_timeout = @params[:http_connection_read_timeout]
+
+ if @protocol == 'https'
+ verifyCallbackProc = Proc.new{ |ok, x509_store_ctx|
+ code = x509_store_ctx.error
+ msg = x509_store_ctx.error_string
+ #debugger
+ @logger.warn("##### #{@server} certificate verify failed: #{msg}") unless code == 0
+ true
+ }
+ @http.use_ssl = true
+ ca_file = get_param(:ca_file)
+ if ca_file
+ @http.verify_mode = OpenSSL::SSL::VERIFY_PEER
+ @http.verify_callback = verifyCallbackProc
+ @http.ca_file = ca_file
+ end
+ end
+ # open connection
+ @http.start
+ end
+
+ public
+
+=begin rdoc
+ Send HTTP request to server
+
+ request_params hash:
+ :server => 'www.HostName.com' # Hostname or IP address of HTTP server
+ :port => '80' # Port of HTTP server
+ :protocol => 'https' # http and https are supported on any port
+ :request => 'requeststring' # Fully-formed HTTP request to make
+
+ Raises RuntimeError, Interrupt, and params[:exception] (if specified in new).
+
+=end
+ def request(request_params, &block)
+ # We save the offset here so that if we need to retry, we can return the file pointer to its initial position
+ mypos = get_fileptr_offset(request_params)
+ loop do
+ # if we are inside a delay between retries: no requests this time!
+ if error_count > @params[:http_connection_retry_count] &&
+ error_time + @params[:http_connection_retry_delay] > Time.now
+ # store the message (otherwise it will be lost after error_reset and
+ # we will raise an exception with an empty text)
+ banana_message_text = banana_message
+ @logger.warn("#{err_header} re-raising same error: #{banana_message_text} " +
+ "-- error count: #{error_count}, error age: #{Time.now.to_i - error_time.to_i}")
+ exception = get_param(:exception) || RuntimeError
+ raise exception.new(banana_message_text)
+ end
+
+ # try to connect server(if connection does not exist) and get response data
+ begin
+ request_params[:protocol] ||= (request_params[:port] == 443 ? 'https' : 'http')
+
+ request = request_params[:request]
+ request['User-Agent'] = get_param(:user_agent) || ''
+
+ # (re)open connection to server if none exists or params has changed
+ unless @http &&
+ @http.started? &&
+ @server == request_params[:server] &&
+ @port == request_params[:port] &&
+ @protocol == request_params[:protocol]
+ start(request_params)
+ end
+
+ # Detect if the body is a streamable object like a file or socket. If so, stream that
+ # bad boy.
+ setup_streaming(request)
+ response = @http.request(request, &block)
+
+ error_reset
+ eof_reset
+ return response
+
+ # We treat EOF errors and the timeout/network errors differently. Both
+ # are tracked in different statistics blocks. Note below that EOF
+ # errors will sleep for a certain (exponentially increasing) period.
+ # Other errors don't sleep because there is already an inherent delay
+ # in them; connect and read timeouts (for example) have already
+ # 'slept'. It is still not clear which way we should treat errors
+ # like RST and resolution failures. For now, there is no additional
+ # delay for these errors although this may change in the future.
+
+ # EOFError means the server closed the connection on us.
+ rescue EOFError => e
+ @logger.debug("#{err_header} server #{@server} closed connection")
+ @http = nil
+
+ # if we have waited long enough - raise an exception...
+ if raise_on_eof_exception?
+ exception = get_param(:exception) || RuntimeError
+ @logger.warn("#{err_header} raising #{exception} due to permanent EOF being received from #{@server}, error age: #{Time.now.to_i - eof_time.to_i}")
+ raise exception.new("Permanent EOF is being received from #{@server}.")
+ else
+ # ... else just sleep a bit before new retry
+ sleep(add_eof)
+ # We will be retrying the request, so reset the file pointer
+ reset_fileptr_offset(request, mypos)
+ end
+ rescue Exception => e # See comment at bottom for the list of errors seen...
+ @http = nil
+ # if ctrl+c is pressed - we have to reraise exception to terminate proggy
+ if e.is_a?(Interrupt) && !( e.is_a?(Errno::ETIMEDOUT) || e.is_a?(Timeout::Error))
+ @logger.debug( "#{err_header} request to server #{@server} interrupted by ctrl-c")
+ raise
+ elsif e.is_a?(ArgumentError) && e.message.include?('wrong number of arguments (5 for 4)')
+ # seems our net_fix patch was overriden...
+ exception = get_param(:exception) || RuntimeError
+ raise exception.new('incompatible Net::HTTP monkey-patch')
+ end
+ # oops - we got a banana: log it
+ error_add(e.message)
+ @logger.warn("#{err_header} request failure count: #{error_count}, exception: #{e.inspect}")
+
+ # We will be retrying the request, so reset the file pointer
+ reset_fileptr_offset(request, mypos)
+
+ end
+ end
+ end
+
+ def finish(reason = '')
+ if @http && @http.started?
+ reason = ", reason: '#{reason}'" unless reason.blank?
+ @logger.info("Closing #{@http.use_ssl? ? 'HTTPS' : 'HTTP'} connection to #{@http.address}:#{@http.port}#{reason}")
+ @http.finish
+ end
+ end
+
+ # Errors received during testing:
+ #
+ # #<Timeout::Error: execution expired>
+ # #<Errno::ETIMEDOUT: Connection timed out - connect(2)>
+ # #<SocketError: getaddrinfo: Name or service not known>
+ # #<SocketError: getaddrinfo: Temporary failure in name resolution>
+ # #<EOFError: end of file reached>
+ # #<Errno::ECONNRESET: Connection reset by peer>
+ # #<OpenSSL::SSL::SSLError: SSL_write:: bad write retry>
+ end
+
+end
+
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/setup.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/setup.rb
new file mode 100644
index 000000000..424a5f37c
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/right_http_connection-1.2.4/setup.rb
@@ -0,0 +1,1585 @@
+#
+# setup.rb
+#
+# Copyright (c) 2000-2005 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the terms of
+# the GNU LGPL, Lesser General Public License version 2.1.
+#
+
+unless Enumerable.method_defined?(:map) # Ruby 1.4.6
+ module Enumerable
+ alias map collect
+ end
+end
+
+unless File.respond_to?(:read) # Ruby 1.6
+ def File.read(fname)
+ open(fname) {|f|
+ return f.read
+ }
+ end
+end
+
+unless Errno.const_defined?(:ENOTEMPTY) # Windows?
+ module Errno
+ class ENOTEMPTY
+ # We do not raise this exception, implementation is not needed.
+ end
+ end
+end
+
+def File.binread(fname)
+ open(fname, 'rb') {|f|
+ return f.read
+ }
+end
+
+# for corrupted Windows' stat(2)
+def File.dir?(path)
+ File.directory?((path[-1,1] == '/') ? path : path + '/')
+end
+
+
+class ConfigTable
+
+ include Enumerable
+
+ def initialize(rbconfig)
+ @rbconfig = rbconfig
+ @items = []
+ @table = {}
+ # options
+ @install_prefix = nil
+ @config_opt = nil
+ @verbose = true
+ @no_harm = false
+ end
+
+ attr_accessor :install_prefix
+ attr_accessor :config_opt
+
+ attr_writer :verbose
+
+ def verbose?
+ @verbose
+ end
+
+ attr_writer :no_harm
+
+ def no_harm?
+ @no_harm
+ end
+
+ def [](key)
+ lookup(key).resolve(self)
+ end
+
+ def []=(key, val)
+ lookup(key).set val
+ end
+
+ def names
+ @items.map {|i| i.name }
+ end
+
+ def each(&block)
+ @items.each(&block)
+ end
+
+ def key?(name)
+ @table.key?(name)
+ end
+
+ def lookup(name)
+ @table[name] or setup_rb_error "no such config item: #{name}"
+ end
+
+ def add(item)
+ @items.push item
+ @table[item.name] = item
+ end
+
+ def remove(name)
+ item = lookup(name)
+ @items.delete_if {|i| i.name == name }
+ @table.delete_if {|name, i| i.name == name }
+ item
+ end
+
+ def load_script(path, inst = nil)
+ if File.file?(path)
+ MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path
+ end
+ end
+
+ def savefile
+ '.config'
+ end
+
+ def load_savefile
+ begin
+ File.foreach(savefile()) do |line|
+ k, v = *line.split(/=/, 2)
+ self[k] = v.strip
+ end
+ rescue Errno::ENOENT
+ setup_rb_error $!.message + "\n#{File.basename($0)} config first"
+ end
+ end
+
+ def save
+ @items.each {|i| i.value }
+ File.open(savefile(), 'w') {|f|
+ @items.each do |i|
+ f.printf "%s=%s\n", i.name, i.value if i.value? and i.value
+ end
+ }
+ end
+
+ def load_standard_entries
+ standard_entries(@rbconfig).each do |ent|
+ add ent
+ end
+ end
+
+ def standard_entries(rbconfig)
+ c = rbconfig
+
+ rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT'])
+
+ major = c['MAJOR'].to_i
+ minor = c['MINOR'].to_i
+ teeny = c['TEENY'].to_i
+ version = "#{major}.#{minor}"
+
+ # ruby ver. >= 1.4.4?
+ newpath_p = ((major >= 2) or
+ ((major == 1) and
+ ((minor >= 5) or
+ ((minor == 4) and (teeny >= 4)))))
+
+ if c['rubylibdir']
+ # V > 1.6.3
+ libruby = "#{c['prefix']}/lib/ruby"
+ librubyver = c['rubylibdir']
+ librubyverarch = c['archdir']
+ siteruby = c['sitedir']
+ siterubyver = c['sitelibdir']
+ siterubyverarch = c['sitearchdir']
+ elsif newpath_p
+ # 1.4.4 <= V <= 1.6.3
+ libruby = "#{c['prefix']}/lib/ruby"
+ librubyver = "#{c['prefix']}/lib/ruby/#{version}"
+ librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
+ siteruby = c['sitedir']
+ siterubyver = "$siteruby/#{version}"
+ siterubyverarch = "$siterubyver/#{c['arch']}"
+ else
+ # V < 1.4.4
+ libruby = "#{c['prefix']}/lib/ruby"
+ librubyver = "#{c['prefix']}/lib/ruby/#{version}"
+ librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
+ siteruby = "#{c['prefix']}/lib/ruby/#{version}/site_ruby"
+ siterubyver = siteruby
+ siterubyverarch = "$siterubyver/#{c['arch']}"
+ end
+ parameterize = lambda {|path|
+ path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')
+ }
+
+ if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
+ makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
+ else
+ makeprog = 'make'
+ end
+
+ [
+ ExecItem.new('installdirs', 'std/site/home',
+ 'std: install under libruby; site: install under site_ruby; home: install under $HOME')\
+ {|val, table|
+ case val
+ when 'std'
+ table['rbdir'] = '$librubyver'
+ table['sodir'] = '$librubyverarch'
+ when 'site'
+ table['rbdir'] = '$siterubyver'
+ table['sodir'] = '$siterubyverarch'
+ when 'home'
+ setup_rb_error '$HOME was not set' unless ENV['HOME']
+ table['prefix'] = ENV['HOME']
+ table['rbdir'] = '$libdir/ruby'
+ table['sodir'] = '$libdir/ruby'
+ end
+ },
+ PathItem.new('prefix', 'path', c['prefix'],
+ 'path prefix of target environment'),
+ PathItem.new('bindir', 'path', parameterize.call(c['bindir']),
+ 'the directory for commands'),
+ PathItem.new('libdir', 'path', parameterize.call(c['libdir']),
+ 'the directory for libraries'),
+ PathItem.new('datadir', 'path', parameterize.call(c['datadir']),
+ 'the directory for shared data'),
+ PathItem.new('mandir', 'path', parameterize.call(c['mandir']),
+ 'the directory for man pages'),
+ PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']),
+ 'the directory for system configuration files'),
+ PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']),
+ 'the directory for local state data'),
+ PathItem.new('libruby', 'path', libruby,
+ 'the directory for ruby libraries'),
+ PathItem.new('librubyver', 'path', librubyver,
+ 'the directory for standard ruby libraries'),
+ PathItem.new('librubyverarch', 'path', librubyverarch,
+ 'the directory for standard ruby extensions'),
+ PathItem.new('siteruby', 'path', siteruby,
+ 'the directory for version-independent aux ruby libraries'),
+ PathItem.new('siterubyver', 'path', siterubyver,
+ 'the directory for aux ruby libraries'),
+ PathItem.new('siterubyverarch', 'path', siterubyverarch,
+ 'the directory for aux ruby binaries'),
+ PathItem.new('rbdir', 'path', '$siterubyver',
+ 'the directory for ruby scripts'),
+ PathItem.new('sodir', 'path', '$siterubyverarch',
+ 'the directory for ruby extentions'),
+ PathItem.new('rubypath', 'path', rubypath,
+ 'the path to set to #! line'),
+ ProgramItem.new('rubyprog', 'name', rubypath,
+ 'the ruby program using for installation'),
+ ProgramItem.new('makeprog', 'name', makeprog,
+ 'the make program to compile ruby extentions'),
+ SelectItem.new('shebang', 'all/ruby/never', 'ruby',
+ 'shebang line (#!) editing mode'),
+ BoolItem.new('without-ext', 'yes/no', 'no',
+ 'does not compile/install ruby extentions')
+ ]
+ end
+ private :standard_entries
+
+ def load_multipackage_entries
+ multipackage_entries().each do |ent|
+ add ent
+ end
+ end
+
+ def multipackage_entries
+ [
+ PackageSelectionItem.new('with', 'name,name...', '', 'ALL',
+ 'package names that you want to install'),
+ PackageSelectionItem.new('without', 'name,name...', '', 'NONE',
+ 'package names that you do not want to install')
+ ]
+ end
+ private :multipackage_entries
+
+ ALIASES = {
+ 'std-ruby' => 'librubyver',
+ 'stdruby' => 'librubyver',
+ 'rubylibdir' => 'librubyver',
+ 'archdir' => 'librubyverarch',
+ 'site-ruby-common' => 'siteruby', # For backward compatibility
+ 'site-ruby' => 'siterubyver', # For backward compatibility
+ 'bin-dir' => 'bindir',
+ 'bin-dir' => 'bindir',
+ 'rb-dir' => 'rbdir',
+ 'so-dir' => 'sodir',
+ 'data-dir' => 'datadir',
+ 'ruby-path' => 'rubypath',
+ 'ruby-prog' => 'rubyprog',
+ 'ruby' => 'rubyprog',
+ 'make-prog' => 'makeprog',
+ 'make' => 'makeprog'
+ }
+
+ def fixup
+ ALIASES.each do |ali, name|
+ @table[ali] = @table[name]
+ end
+ @items.freeze
+ @table.freeze
+ @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/
+ end
+
+ def parse_opt(opt)
+ m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}"
+ m.to_a[1,2]
+ end
+
+ def dllext
+ @rbconfig['DLEXT']
+ end
+
+ def value_config?(name)
+ lookup(name).value?
+ end
+
+ class Item
+ def initialize(name, template, default, desc)
+ @name = name.freeze
+ @template = template
+ @value = default
+ @default = default
+ @description = desc
+ end
+
+ attr_reader :name
+ attr_reader :description
+
+ attr_accessor :default
+ alias help_default default
+
+ def help_opt
+ "--#{@name}=#{@template}"
+ end
+
+ def value?
+ true
+ end
+
+ def value
+ @value
+ end
+
+ def resolve(table)
+ @value.gsub(%r<\$([^/]+)>) { table[$1] }
+ end
+
+ def set(val)
+ @value = check(val)
+ end
+
+ private
+
+ def check(val)
+ setup_rb_error "config: --#{name} requires argument" unless val
+ val
+ end
+ end
+
+ class BoolItem < Item
+ def config_type
+ 'bool'
+ end
+
+ def help_opt
+ "--#{@name}"
+ end
+
+ private
+
+ def check(val)
+ return 'yes' unless val
+ case val
+ when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes'
+ when /\An(o)?\z/i, /\Af(alse)\z/i then 'no'
+ else
+ setup_rb_error "config: --#{@name} accepts only yes/no for argument"
+ end
+ end
+ end
+
+ class PathItem < Item
+ def config_type
+ 'path'
+ end
+
+ private
+
+ def check(path)
+ setup_rb_error "config: --#{@name} requires argument" unless path
+ path[0,1] == '$' ? path : File.expand_path(path)
+ end
+ end
+
+ class ProgramItem < Item
+ def config_type
+ 'program'
+ end
+ end
+
+ class SelectItem < Item
+ def initialize(name, selection, default, desc)
+ super
+ @ok = selection.split('/')
+ end
+
+ def config_type
+ 'select'
+ end
+
+ private
+
+ def check(val)
+ unless @ok.include?(val.strip)
+ setup_rb_error "config: use --#{@name}=#{@template} (#{val})"
+ end
+ val.strip
+ end
+ end
+
+ class ExecItem < Item
+ def initialize(name, selection, desc, &block)
+ super name, selection, nil, desc
+ @ok = selection.split('/')
+ @action = block
+ end
+
+ def config_type
+ 'exec'
+ end
+
+ def value?
+ false
+ end
+
+ def resolve(table)
+ setup_rb_error "$#{name()} wrongly used as option value"
+ end
+
+ undef set
+
+ def evaluate(val, table)
+ v = val.strip.downcase
+ unless @ok.include?(v)
+ setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})"
+ end
+ @action.call v, table
+ end
+ end
+
+ class PackageSelectionItem < Item
+ def initialize(name, template, default, help_default, desc)
+ super name, template, default, desc
+ @help_default = help_default
+ end
+
+ attr_reader :help_default
+
+ def config_type
+ 'package'
+ end
+
+ private
+
+ def check(val)
+ unless File.dir?("packages/#{val}")
+ setup_rb_error "config: no such package: #{val}"
+ end
+ val
+ end
+ end
+
+ class MetaConfigEnvironment
+ def initialize(config, installer)
+ @config = config
+ @installer = installer
+ end
+
+ def config_names
+ @config.names
+ end
+
+ def config?(name)
+ @config.key?(name)
+ end
+
+ def bool_config?(name)
+ @config.lookup(name).config_type == 'bool'
+ end
+
+ def path_config?(name)
+ @config.lookup(name).config_type == 'path'
+ end
+
+ def value_config?(name)
+ @config.lookup(name).config_type != 'exec'
+ end
+
+ def add_config(item)
+ @config.add item
+ end
+
+ def add_bool_config(name, default, desc)
+ @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc)
+ end
+
+ def add_path_config(name, default, desc)
+ @config.add PathItem.new(name, 'path', default, desc)
+ end
+
+ def set_config_default(name, default)
+ @config.lookup(name).default = default
+ end
+
+ def remove_config(name)
+ @config.remove(name)
+ end
+
+ # For only multipackage
+ def packages
+ raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer
+ @installer.packages
+ end
+
+ # For only multipackage
+ def declare_packages(list)
+ raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer
+ @installer.packages = list
+ end
+ end
+
+end # class ConfigTable
+
+
+# This module requires: #verbose?, #no_harm?
+module FileOperations
+
+ def mkdir_p(dirname, prefix = nil)
+ dirname = prefix + File.expand_path(dirname) if prefix
+ $stderr.puts "mkdir -p #{dirname}" if verbose?
+ return if no_harm?
+
+ # Does not check '/', it's too abnormal.
+ dirs = File.expand_path(dirname).split(%r<(?=/)>)
+ if /\A[a-z]:\z/i =~ dirs[0]
+ disk = dirs.shift
+ dirs[0] = disk + dirs[0]
+ end
+ dirs.each_index do |idx|
+ path = dirs[0..idx].join('')
+ Dir.mkdir path unless File.dir?(path)
+ end
+ end
+
+ def rm_f(path)
+ $stderr.puts "rm -f #{path}" if verbose?
+ return if no_harm?
+ force_remove_file path
+ end
+
+ def rm_rf(path)
+ $stderr.puts "rm -rf #{path}" if verbose?
+ return if no_harm?
+ remove_tree path
+ end
+
+ def remove_tree(path)
+ if File.symlink?(path)
+ remove_file path
+ elsif File.dir?(path)
+ remove_tree0 path
+ else
+ force_remove_file path
+ end
+ end
+
+ def remove_tree0(path)
+ Dir.foreach(path) do |ent|
+ next if ent == '.'
+ next if ent == '..'
+ entpath = "#{path}/#{ent}"
+ if File.symlink?(entpath)
+ remove_file entpath
+ elsif File.dir?(entpath)
+ remove_tree0 entpath
+ else
+ force_remove_file entpath
+ end
+ end
+ begin
+ Dir.rmdir path
+ rescue Errno::ENOTEMPTY
+ # directory may not be empty
+ end
+ end
+
+ def move_file(src, dest)
+ force_remove_file dest
+ begin
+ File.rename src, dest
+ rescue
+ File.open(dest, 'wb') {|f|
+ f.write File.binread(src)
+ }
+ File.chmod File.stat(src).mode, dest
+ File.unlink src
+ end
+ end
+
+ def force_remove_file(path)
+ begin
+ remove_file path
+ rescue
+ end
+ end
+
+ def remove_file(path)
+ File.chmod 0777, path
+ File.unlink path
+ end
+
+ def install(from, dest, mode, prefix = nil)
+ $stderr.puts "install #{from} #{dest}" if verbose?
+ return if no_harm?
+
+ realdest = prefix ? prefix + File.expand_path(dest) : dest
+ realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
+ str = File.binread(from)
+ if diff?(str, realdest)
+ verbose_off {
+ rm_f realdest if File.exist?(realdest)
+ }
+ File.open(realdest, 'wb') {|f|
+ f.write str
+ }
+ File.chmod mode, realdest
+
+ File.open("#{objdir_root()}/InstalledFiles", 'a') {|f|
+ if prefix
+ f.puts realdest.sub(prefix, '')
+ else
+ f.puts realdest
+ end
+ }
+ end
+ end
+
+ def diff?(new_content, path)
+ return true unless File.exist?(path)
+ new_content != File.binread(path)
+ end
+
+ def command(*args)
+ $stderr.puts args.join(' ') if verbose?
+ system(*args) or raise RuntimeError,
+ "system(#{args.map{|a| a.inspect }.join(' ')}) failed"
+ end
+
+ def ruby(*args)
+ command config('rubyprog'), *args
+ end
+
+ def make(task = nil)
+ command(*[config('makeprog'), task].compact)
+ end
+
+ def extdir?(dir)
+ File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb")
+ end
+
+ def files_of(dir)
+ Dir.open(dir) {|d|
+ return d.select {|ent| File.file?("#{dir}/#{ent}") }
+ }
+ end
+
+ DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn )
+
+ def directories_of(dir)
+ Dir.open(dir) {|d|
+ return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT
+ }
+ end
+
+end
+
+
+# This module requires: #srcdir_root, #objdir_root, #relpath
+module HookScriptAPI
+
+ def get_config(key)
+ @config[key]
+ end
+
+ alias config get_config
+
+ # obsolete: use metaconfig to change configuration
+ def set_config(key, val)
+ @config[key] = val
+ end
+
+ #
+ # srcdir/objdir (works only in the package directory)
+ #
+
+ def curr_srcdir
+ "#{srcdir_root()}/#{relpath()}"
+ end
+
+ def curr_objdir
+ "#{objdir_root()}/#{relpath()}"
+ end
+
+ def srcfile(path)
+ "#{curr_srcdir()}/#{path}"
+ end
+
+ def srcexist?(path)
+ File.exist?(srcfile(path))
+ end
+
+ def srcdirectory?(path)
+ File.dir?(srcfile(path))
+ end
+
+ def srcfile?(path)
+ File.file?(srcfile(path))
+ end
+
+ def srcentries(path = '.')
+ Dir.open("#{curr_srcdir()}/#{path}") {|d|
+ return d.to_a - %w(. ..)
+ }
+ end
+
+ def srcfiles(path = '.')
+ srcentries(path).select {|fname|
+ File.file?(File.join(curr_srcdir(), path, fname))
+ }
+ end
+
+ def srcdirectories(path = '.')
+ srcentries(path).select {|fname|
+ File.dir?(File.join(curr_srcdir(), path, fname))
+ }
+ end
+
+end
+
+
+class ToplevelInstaller
+
+ Version = '3.4.1'
+ Copyright = 'Copyright (c) 2000-2005 Minero Aoki'
+
+ TASKS = [
+ [ 'all', 'do config, setup, then install' ],
+ [ 'config', 'saves your configurations' ],
+ [ 'show', 'shows current configuration' ],
+ [ 'setup', 'compiles ruby extentions and others' ],
+ [ 'install', 'installs files' ],
+ [ 'test', 'run all tests in test/' ],
+ [ 'clean', "does `make clean' for each extention" ],
+ [ 'distclean',"does `make distclean' for each extention" ]
+ ]
+
+ def ToplevelInstaller.invoke
+ config = ConfigTable.new(load_rbconfig())
+ config.load_standard_entries
+ config.load_multipackage_entries if multipackage?
+ config.fixup
+ klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller)
+ klass.new(File.dirname($0), config).invoke
+ end
+
+ def ToplevelInstaller.multipackage?
+ File.dir?(File.dirname($0) + '/packages')
+ end
+
+ def ToplevelInstaller.load_rbconfig
+ if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
+ ARGV.delete(arg)
+ load File.expand_path(arg.split(/=/, 2)[1])
+ $".push 'rbconfig.rb'
+ else
+ require 'rbconfig'
+ end
+ ::Config::CONFIG
+ end
+
+ def initialize(ardir_root, config)
+ @ardir = File.expand_path(ardir_root)
+ @config = config
+ # cache
+ @valid_task_re = nil
+ end
+
+ def config(key)
+ @config[key]
+ end
+
+ def inspect
+ "#<#{self.class} #{__id__()}>"
+ end
+
+ def invoke
+ run_metaconfigs
+ case task = parsearg_global()
+ when nil, 'all'
+ parsearg_config
+ init_installers
+ exec_config
+ exec_setup
+ exec_install
+ else
+ case task
+ when 'config', 'test'
+ ;
+ when 'clean', 'distclean'
+ @config.load_savefile if File.exist?(@config.savefile)
+ else
+ @config.load_savefile
+ end
+ __send__ "parsearg_#{task}"
+ init_installers
+ __send__ "exec_#{task}"
+ end
+ end
+
+ def run_metaconfigs
+ @config.load_script "#{@ardir}/metaconfig"
+ end
+
+ def init_installers
+ @installer = Installer.new(@config, @ardir, File.expand_path('.'))
+ end
+
+ #
+ # Hook Script API bases
+ #
+
+ def srcdir_root
+ @ardir
+ end
+
+ def objdir_root
+ '.'
+ end
+
+ def relpath
+ '.'
+ end
+
+ #
+ # Option Parsing
+ #
+
+ def parsearg_global
+ while arg = ARGV.shift
+ case arg
+ when /\A\w+\z/
+ setup_rb_error "invalid task: #{arg}" unless valid_task?(arg)
+ return arg
+ when '-q', '--quiet'
+ @config.verbose = false
+ when '--verbose'
+ @config.verbose = true
+ when '--help'
+ print_usage $stdout
+ exit 0
+ when '--version'
+ puts "#{File.basename($0)} version #{Version}"
+ exit 0
+ when '--copyright'
+ puts Copyright
+ exit 0
+ else
+ setup_rb_error "unknown global option '#{arg}'"
+ end
+ end
+ nil
+ end
+
+ def valid_task?(t)
+ valid_task_re() =~ t
+ end
+
+ def valid_task_re
+ @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/
+ end
+
+ def parsearg_no_options
+ unless ARGV.empty?
+ task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1)
+ setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}"
+ end
+ end
+
+ alias parsearg_show parsearg_no_options
+ alias parsearg_setup parsearg_no_options
+ alias parsearg_test parsearg_no_options
+ alias parsearg_clean parsearg_no_options
+ alias parsearg_distclean parsearg_no_options
+
+ def parsearg_config
+ evalopt = []
+ set = []
+ @config.config_opt = []
+ while i = ARGV.shift
+ if /\A--?\z/ =~ i
+ @config.config_opt = ARGV.dup
+ break
+ end
+ name, value = *@config.parse_opt(i)
+ if @config.value_config?(name)
+ @config[name] = value
+ else
+ evalopt.push [name, value]
+ end
+ set.push name
+ end
+ evalopt.each do |name, value|
+ @config.lookup(name).evaluate value, @config
+ end
+ # Check if configuration is valid
+ set.each do |n|
+ @config[n] if @config.value_config?(n)
+ end
+ end
+
+ def parsearg_install
+ @config.no_harm = false
+ @config.install_prefix = ''
+ while a = ARGV.shift
+ case a
+ when '--no-harm'
+ @config.no_harm = true
+ when /\A--prefix=/
+ path = a.split(/=/, 2)[1]
+ path = File.expand_path(path) unless path[0,1] == '/'
+ @config.install_prefix = path
+ else
+ setup_rb_error "install: unknown option #{a}"
+ end
+ end
+ end
+
+ def print_usage(out)
+ out.puts 'Typical Installation Procedure:'
+ out.puts " $ ruby #{File.basename $0} config"
+ out.puts " $ ruby #{File.basename $0} setup"
+ out.puts " # ruby #{File.basename $0} install (may require root privilege)"
+ out.puts
+ out.puts 'Detailed Usage:'
+ out.puts " ruby #{File.basename $0} <global option>"
+ out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]"
+
+ fmt = " %-24s %s\n"
+ out.puts
+ out.puts 'Global options:'
+ out.printf fmt, '-q,--quiet', 'suppress message outputs'
+ out.printf fmt, ' --verbose', 'output messages verbosely'
+ out.printf fmt, ' --help', 'print this message'
+ out.printf fmt, ' --version', 'print version and quit'
+ out.printf fmt, ' --copyright', 'print copyright and quit'
+ out.puts
+ out.puts 'Tasks:'
+ TASKS.each do |name, desc|
+ out.printf fmt, name, desc
+ end
+
+ fmt = " %-24s %s [%s]\n"
+ out.puts
+ out.puts 'Options for CONFIG or ALL:'
+ @config.each do |item|
+ out.printf fmt, item.help_opt, item.description, item.help_default
+ end
+ out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's"
+ out.puts
+ out.puts 'Options for INSTALL:'
+ out.printf fmt, '--no-harm', 'only display what to do if given', 'off'
+ out.printf fmt, '--prefix=path', 'install path prefix', ''
+ out.puts
+ end
+
+ #
+ # Task Handlers
+ #
+
+ def exec_config
+ @installer.exec_config
+ @config.save # must be final
+ end
+
+ def exec_setup
+ @installer.exec_setup
+ end
+
+ def exec_install
+ @installer.exec_install
+ end
+
+ def exec_test
+ @installer.exec_test
+ end
+
+ def exec_show
+ @config.each do |i|
+ printf "%-20s %s\n", i.name, i.value if i.value?
+ end
+ end
+
+ def exec_clean
+ @installer.exec_clean
+ end
+
+ def exec_distclean
+ @installer.exec_distclean
+ end
+
+end # class ToplevelInstaller
+
+
+class ToplevelInstallerMulti < ToplevelInstaller
+
+ include FileOperations
+
+ def initialize(ardir_root, config)
+ super
+ @packages = directories_of("#{@ardir}/packages")
+ raise 'no package exists' if @packages.empty?
+ @root_installer = Installer.new(@config, @ardir, File.expand_path('.'))
+ end
+
+ def run_metaconfigs
+ @config.load_script "#{@ardir}/metaconfig", self
+ @packages.each do |name|
+ @config.load_script "#{@ardir}/packages/#{name}/metaconfig"
+ end
+ end
+
+ attr_reader :packages
+
+ def packages=(list)
+ raise 'package list is empty' if list.empty?
+ list.each do |name|
+ raise "directory packages/#{name} does not exist"\
+ unless File.dir?("#{@ardir}/packages/#{name}")
+ end
+ @packages = list
+ end
+
+ def init_installers
+ @installers = {}
+ @packages.each do |pack|
+ @installers[pack] = Installer.new(@config,
+ "#{@ardir}/packages/#{pack}",
+ "packages/#{pack}")
+ end
+ with = extract_selection(config('with'))
+ without = extract_selection(config('without'))
+ @selected = @installers.keys.select {|name|
+ (with.empty? or with.include?(name)) \
+ and not without.include?(name)
+ }
+ end
+
+ def extract_selection(list)
+ a = list.split(/,/)
+ a.each do |name|
+ setup_rb_error "no such package: #{name}" unless @installers.key?(name)
+ end
+ a
+ end
+
+ def print_usage(f)
+ super
+ f.puts 'Inluded packages:'
+ f.puts ' ' + @packages.sort.join(' ')
+ f.puts
+ end
+
+ #
+ # Task Handlers
+ #
+
+ def exec_config
+ run_hook 'pre-config'
+ each_selected_installers {|inst| inst.exec_config }
+ run_hook 'post-config'
+ @config.save # must be final
+ end
+
+ def exec_setup
+ run_hook 'pre-setup'
+ each_selected_installers {|inst| inst.exec_setup }
+ run_hook 'post-setup'
+ end
+
+ def exec_install
+ run_hook 'pre-install'
+ each_selected_installers {|inst| inst.exec_install }
+ run_hook 'post-install'
+ end
+
+ def exec_test
+ run_hook 'pre-test'
+ each_selected_installers {|inst| inst.exec_test }
+ run_hook 'post-test'
+ end
+
+ def exec_clean
+ rm_f @config.savefile
+ run_hook 'pre-clean'
+ each_selected_installers {|inst| inst.exec_clean }
+ run_hook 'post-clean'
+ end
+
+ def exec_distclean
+ rm_f @config.savefile
+ run_hook 'pre-distclean'
+ each_selected_installers {|inst| inst.exec_distclean }
+ run_hook 'post-distclean'
+ end
+
+ #
+ # lib
+ #
+
+ def each_selected_installers
+ Dir.mkdir 'packages' unless File.dir?('packages')
+ @selected.each do |pack|
+ $stderr.puts "Processing the package `#{pack}' ..." if verbose?
+ Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
+ Dir.chdir "packages/#{pack}"
+ yield @installers[pack]
+ Dir.chdir '../..'
+ end
+ end
+
+ def run_hook(id)
+ @root_installer.run_hook id
+ end
+
+ # module FileOperations requires this
+ def verbose?
+ @config.verbose?
+ end
+
+ # module FileOperations requires this
+ def no_harm?
+ @config.no_harm?
+ end
+
+end # class ToplevelInstallerMulti
+
+
+class Installer
+
+ FILETYPES = %w( bin lib ext data conf man )
+
+ include FileOperations
+ include HookScriptAPI
+
+ def initialize(config, srcroot, objroot)
+ @config = config
+ @srcdir = File.expand_path(srcroot)
+ @objdir = File.expand_path(objroot)
+ @currdir = '.'
+ end
+
+ def inspect
+ "#<#{self.class} #{File.basename(@srcdir)}>"
+ end
+
+ def noop(rel)
+ end
+
+ #
+ # Hook Script API base methods
+ #
+
+ def srcdir_root
+ @srcdir
+ end
+
+ def objdir_root
+ @objdir
+ end
+
+ def relpath
+ @currdir
+ end
+
+ #
+ # Config Access
+ #
+
+ # module FileOperations requires this
+ def verbose?
+ @config.verbose?
+ end
+
+ # module FileOperations requires this
+ def no_harm?
+ @config.no_harm?
+ end
+
+ def verbose_off
+ begin
+ save, @config.verbose = @config.verbose?, false
+ yield
+ ensure
+ @config.verbose = save
+ end
+ end
+
+ #
+ # TASK config
+ #
+
+ def exec_config
+ exec_task_traverse 'config'
+ end
+
+ alias config_dir_bin noop
+ alias config_dir_lib noop
+
+ def config_dir_ext(rel)
+ extconf if extdir?(curr_srcdir())
+ end
+
+ alias config_dir_data noop
+ alias config_dir_conf noop
+ alias config_dir_man noop
+
+ def extconf
+ ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt
+ end
+
+ #
+ # TASK setup
+ #
+
+ def exec_setup
+ exec_task_traverse 'setup'
+ end
+
+ def setup_dir_bin(rel)
+ files_of(curr_srcdir()).each do |fname|
+ update_shebang_line "#{curr_srcdir()}/#{fname}"
+ end
+ end
+
+ alias setup_dir_lib noop
+
+ def setup_dir_ext(rel)
+ make if extdir?(curr_srcdir())
+ end
+
+ alias setup_dir_data noop
+ alias setup_dir_conf noop
+ alias setup_dir_man noop
+
+ def update_shebang_line(path)
+ return if no_harm?
+ return if config('shebang') == 'never'
+ old = Shebang.load(path)
+ if old
+ $stderr.puts "warning: #{path}: Shebang line includes too many args. It is not portable and your program may not work." if old.args.size > 1
+ new = new_shebang(old)
+ return if new.to_s == old.to_s
+ else
+ return unless config('shebang') == 'all'
+ new = Shebang.new(config('rubypath'))
+ end
+ $stderr.puts "updating shebang: #{File.basename(path)}" if verbose?
+ open_atomic_writer(path) {|output|
+ File.open(path, 'rb') {|f|
+ f.gets if old # discard
+ output.puts new.to_s
+ output.print f.read
+ }
+ }
+ end
+
+ def new_shebang(old)
+ if /\Aruby/ =~ File.basename(old.cmd)
+ Shebang.new(config('rubypath'), old.args)
+ elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby'
+ Shebang.new(config('rubypath'), old.args[1..-1])
+ else
+ return old unless config('shebang') == 'all'
+ Shebang.new(config('rubypath'))
+ end
+ end
+
+ def open_atomic_writer(path, &block)
+ tmpfile = File.basename(path) + '.tmp'
+ begin
+ File.open(tmpfile, 'wb', &block)
+ File.rename tmpfile, File.basename(path)
+ ensure
+ File.unlink tmpfile if File.exist?(tmpfile)
+ end
+ end
+
+ class Shebang
+ def Shebang.load(path)
+ line = nil
+ File.open(path) {|f|
+ line = f.gets
+ }
+ return nil unless /\A#!/ =~ line
+ parse(line)
+ end
+
+ def Shebang.parse(line)
+ cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ')
+ new(cmd, args)
+ end
+
+ def initialize(cmd, args = [])
+ @cmd = cmd
+ @args = args
+ end
+
+ attr_reader :cmd
+ attr_reader :args
+
+ def to_s
+ "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}")
+ end
+ end
+
+ #
+ # TASK install
+ #
+
+ def exec_install
+ rm_f 'InstalledFiles'
+ exec_task_traverse 'install'
+ end
+
+ def install_dir_bin(rel)
+ install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755
+ end
+
+ def install_dir_lib(rel)
+ install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644
+ end
+
+ def install_dir_ext(rel)
+ return unless extdir?(curr_srcdir())
+ install_files rubyextentions('.'),
+ "#{config('sodir')}/#{File.dirname(rel)}",
+ 0555
+ end
+
+ def install_dir_data(rel)
+ install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644
+ end
+
+ def install_dir_conf(rel)
+ # FIXME: should not remove current config files
+ # (rename previous file to .old/.org)
+ install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644
+ end
+
+ def install_dir_man(rel)
+ install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644
+ end
+
+ def install_files(list, dest, mode)
+ mkdir_p dest, @config.install_prefix
+ list.each do |fname|
+ install fname, dest, mode, @config.install_prefix
+ end
+ end
+
+ def libfiles
+ glob_reject(%w(*.y *.output), targetfiles())
+ end
+
+ def rubyextentions(dir)
+ ents = glob_select("*.#{@config.dllext}", targetfiles())
+ if ents.empty?
+ setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first"
+ end
+ ents
+ end
+
+ def targetfiles
+ mapdir(existfiles() - hookfiles())
+ end
+
+ def mapdir(ents)
+ ents.map {|ent|
+ if File.exist?(ent)
+ then ent # objdir
+ else "#{curr_srcdir()}/#{ent}" # srcdir
+ end
+ }
+ end
+
+ # picked up many entries from cvs-1.11.1/src/ignore.c
+ JUNK_FILES = %w(
+ core RCSLOG tags TAGS .make.state
+ .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
+ *~ *.old *.bak *.BAK *.orig *.rej _$* *$
+
+ *.org *.in .*
+ )
+
+ def existfiles
+ glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.')))
+ end
+
+ def hookfiles
+ %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|
+ %w( config setup install clean ).map {|t| sprintf(fmt, t) }
+ }.flatten
+ end
+
+ def glob_select(pat, ents)
+ re = globs2re([pat])
+ ents.select {|ent| re =~ ent }
+ end
+
+ def glob_reject(pats, ents)
+ re = globs2re(pats)
+ ents.reject {|ent| re =~ ent }
+ end
+
+ GLOB2REGEX = {
+ '.' => '\.',
+ '$' => '\$',
+ '#' => '\#',
+ '*' => '.*'
+ }
+
+ def globs2re(pats)
+ /\A(?:#{
+ pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|')
+ })\z/
+ end
+
+ #
+ # TASK test
+ #
+
+ TESTDIR = 'test'
+
+ def exec_test
+ unless File.directory?('test')
+ $stderr.puts 'no test in this package' if verbose?
+ return
+ end
+ $stderr.puts 'Running tests...' if verbose?
+ begin
+ require 'test/unit'
+ rescue LoadError
+ setup_rb_error 'test/unit cannot loaded. You need Ruby 1.8 or later to invoke this task.'
+ end
+ runner = Test::Unit::AutoRunner.new(true)
+ runner.to_run << TESTDIR
+ runner.run
+ end
+
+ #
+ # TASK clean
+ #
+
+ def exec_clean
+ exec_task_traverse 'clean'
+ rm_f @config.savefile
+ rm_f 'InstalledFiles'
+ end
+
+ alias clean_dir_bin noop
+ alias clean_dir_lib noop
+ alias clean_dir_data noop
+ alias clean_dir_conf noop
+ alias clean_dir_man noop
+
+ def clean_dir_ext(rel)
+ return unless extdir?(curr_srcdir())
+ make 'clean' if File.file?('Makefile')
+ end
+
+ #
+ # TASK distclean
+ #
+
+ def exec_distclean
+ exec_task_traverse 'distclean'
+ rm_f @config.savefile
+ rm_f 'InstalledFiles'
+ end
+
+ alias distclean_dir_bin noop
+ alias distclean_dir_lib noop
+
+ def distclean_dir_ext(rel)
+ return unless extdir?(curr_srcdir())
+ make 'distclean' if File.file?('Makefile')
+ end
+
+ alias distclean_dir_data noop
+ alias distclean_dir_conf noop
+ alias distclean_dir_man noop
+
+ #
+ # Traversing
+ #
+
+ def exec_task_traverse(task)
+ run_hook "pre-#{task}"
+ FILETYPES.each do |type|
+ if type == 'ext' and config('without-ext') == 'yes'
+ $stderr.puts 'skipping ext/* by user option' if verbose?
+ next
+ end
+ traverse task, type, "#{task}_dir_#{type}"
+ end
+ run_hook "post-#{task}"
+ end
+
+ def traverse(task, rel, mid)
+ dive_into(rel) {
+ run_hook "pre-#{task}"
+ __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
+ directories_of(curr_srcdir()).each do |d|
+ traverse task, "#{rel}/#{d}", mid
+ end
+ run_hook "post-#{task}"
+ }
+ end
+
+ def dive_into(rel)
+ return unless File.dir?("#{@srcdir}/#{rel}")
+
+ dir = File.basename(rel)
+ Dir.mkdir dir unless File.dir?(dir)
+ prevdir = Dir.pwd
+ Dir.chdir dir
+ $stderr.puts '---> ' + rel if verbose?
+ @currdir = rel
+ yield
+ Dir.chdir prevdir
+ $stderr.puts '<--- ' + rel if verbose?
+ @currdir = File.dirname(rel)
+ end
+
+ def run_hook(id)
+ path = [ "#{curr_srcdir()}/#{id}",
+ "#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) }
+ return unless path
+ begin
+ instance_eval File.read(path), path, 1
+ rescue
+ raise if $DEBUG
+ setup_rb_error "hook #{path} failed:\n" + $!.message
+ end
+ end
+
+end # class Installer
+
+
+class SetupError < StandardError; end
+
+def setup_rb_error(msg)
+ raise SetupError, msg
+end
+
+if $0 == __FILE__
+ begin
+ ToplevelInstaller.invoke
+ rescue SetupError
+ raise if $DEBUG
+ $stderr.puts $!.message
+ $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
+ exit 1
+ end
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/.document b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/.document
new file mode 100644
index 000000000..ecf367319
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/.document
@@ -0,0 +1,5 @@
+README.rdoc
+lib/**/*.rb
+bin/*
+features/**/*.feature
+LICENSE
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/.gitignore b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/.gitignore
new file mode 100644
index 000000000..482f92bf7
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/.gitignore
@@ -0,0 +1,5 @@
+.DS_Store
+.yardoc
+/coverage
+/doc
+/pkg
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/LICENSE b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/LICENSE
new file mode 100644
index 000000000..590bcb6fa
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/LICENSE
@@ -0,0 +1,20 @@
+Copyright 2009 Chris Kampmeier
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/README.rdoc b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/README.rdoc
new file mode 100644
index 000000000..cfab5434f
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/README.rdoc
@@ -0,0 +1,70 @@
+= Samuel
+
+Samuel is a gem for automatic logging of your Net::HTTP requests. It's named for
+the serial diarist Mr. Pepys, who was known to reliably record events both
+quotidian and remarkable.
+
+Should a Great Plague, Fire, or Whale befall an important external web service
+you use, you'll be sure to have a tidy record of it.
+
+== Usage:
+
+When Rails is loaded, Samuel configures a few things automatically. So all you
+need to do is this:
+
+ # config/environment.rb
+ config.gem "samuel"
+
+And Samuel will automatically use Rails's logger and an ActiveRecord-like format.
+
+For non-Rails projects, you'll have to manually configure logging, like this:
+
+ require 'samuel'
+ Samuel.logger = Logger.new('http_requests.log')
+
+If you don't assign a logger, Samuel will configure a default logger on +STDOUT+.
+
+== Configuration
+
+There are two ways to specify configuration options for Samuel: global and
+inline. Global configs look like this:
+
+ Samuel.config[:labels] = {"example.com" => "Example API"}
+ Samuel.config[:filtered_params] = :password
+
+You should put global configuration somewhere early-on in your program. If
+you're using Rails, <tt>config/initializers/samuel.rb</tt> will do the trick.
+
+Alternatively, an inline configuration block temporarily overrides any global
+configuration for a set of HTTP requests:
+
+ Samuel.with_config :label => "Twitter API" do
+ Net::HTTP.start("twitter.com") { |http| http.get("/help/test") }
+ end
+
+Right now, there are three configuration changes you can make in either style:
+
+* +:labels+ - This is a hash with domain substrings as keys and log labels as
+ values. If a request domain includes one of the domain substrings, the
+ corresponding label will be used for the first part of that log entry. By
+ default this is set to <tt>\{"" => "HTTP"}</tt>, so that all requests are
+ labeled with <tt>"HTTP Request"</tt>.
+* +:label+ - As an alternative to the +:labels+ hash, this is simply a string.
+ If set, it takes precedence over any +:labels+ (by default, it's not set). It
+ gets <tt>"Request"</tt> appended to it as well -- so if you want your log to
+ always say +Twitter API Request+ instead of the default +HTTP Request+, you
+ can set this to <tt>"Twitter API"</tt>. I'd recommend using this setting
+ globally if you're only making requests to one service, or inline if you just
+ need to temporarily override the global +:labels+.
+* +:filtered_params+ - This works just like Rails's +filter_parameter_logging+
+ method. Set it to a symbol, string, or array of them, and Samuel will filter
+ the value of query parameters that have any of these patterns as a substring
+ by replacing the value with <tt>[FILTERED]</tt> in your logs. By default, no
+ filtering is enabled.
+
+Samuel logs successful HTTP requests at the +INFO+ level; Failed requests log at
+the +WARN+ level. This isn't currently configurable, but it's on the list.
+
+== License
+
+Copyright 2009 Chris Kampmeier. See +LICENSE+ for details.
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/Rakefile b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/Rakefile
new file mode 100644
index 000000000..ffbe60384
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/Rakefile
@@ -0,0 +1,62 @@
+require 'rubygems'
+require 'rake'
+
+begin
+ require 'jeweler'
+ Jeweler::Tasks.new do |gem|
+ gem.name = "samuel"
+ gem.summary = %Q{An automatic logger for HTTP requests in Ruby}
+ gem.description = %Q{An automatic logger for HTTP requests in Ruby. Adds Net::HTTP request logging to your Rails logs, and more.}
+ gem.email = "chris@kampers.net"
+ gem.homepage = "http://github.com/chrisk/samuel"
+ gem.authors = ["Chris Kampmeier"]
+ gem.rubyforge_project = "samuel"
+ gem.add_development_dependency "thoughtbot-shoulda"
+ gem.add_development_dependency "yard"
+ gem.add_development_dependency "mocha"
+ gem.add_development_dependency "fakeweb"
+ end
+ Jeweler::GemcutterTasks.new
+ Jeweler::RubyforgeTasks.new do |rubyforge|
+ rubyforge.doc_task = "yardoc"
+ end
+rescue LoadError
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
+end
+
+require 'rake/testtask'
+Rake::TestTask.new(:test) do |test|
+ test.libs << 'lib' << 'test'
+ test.pattern = 'test/**/*_test.rb'
+ test.verbose = false
+ test.warning = true
+end
+
+begin
+ require 'rcov/rcovtask'
+ Rcov::RcovTask.new do |test|
+ test.libs << 'test'
+ test.pattern = 'test/**/*_test.rb'
+ test.rcov_opts << "--sort coverage"
+ test.rcov_opts << "--exclude gems"
+ test.verbose = false
+ test.warning = true
+ end
+rescue LoadError
+ task :rcov do
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
+ end
+end
+
+task :test => :check_dependencies
+
+task :default => :test
+
+begin
+ require 'yard'
+ YARD::Rake::YardocTask.new
+rescue LoadError
+ task :yardoc do
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
+ end
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/VERSION b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/VERSION
new file mode 100644
index 000000000..0c62199f1
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/VERSION
@@ -0,0 +1 @@
+0.2.1
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel.rb
new file mode 100644
index 000000000..5c8fed6f6
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel.rb
@@ -0,0 +1,52 @@
+require "logger"
+require "net/http"
+require "net/https"
+require "benchmark"
+
+require "samuel/net_http"
+require "samuel/request"
+
+
+module Samuel
+ extend self
+
+ attr_writer :config, :logger
+
+ def logger
+ @logger = nil if !defined?(@logger)
+ return @logger if !@logger.nil?
+
+ if defined?(RAILS_DEFAULT_LOGGER)
+ @logger = RAILS_DEFAULT_LOGGER
+ else
+ @logger = Logger.new(STDOUT)
+ end
+ end
+
+ def config
+ Thread.current[:__samuel_config] ? Thread.current[:__samuel_config] : @config
+ end
+
+ def log_request(http, request, &block)
+ request = Request.new(http, request, block)
+ request.perform_and_log!
+ request.response
+ end
+
+ def with_config(options = {})
+ original_config = config.dup
+ nested = !Thread.current[:__samuel_config].nil?
+
+ Thread.current[:__samuel_config] = original_config.merge(options)
+ yield
+ Thread.current[:__samuel_config] = nested ? original_config : nil
+ end
+
+ def reset_config
+ Thread.current[:__samuel_config] = nil
+ @config = {:label => nil, :labels => {"" => "HTTP"}, :filtered_params => []}
+ end
+
+end
+
+Samuel.reset_config
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel/net_http.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel/net_http.rb
new file mode 100644
index 000000000..2ffadf220
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel/net_http.rb
@@ -0,0 +1,10 @@
+class Net::HTTP
+
+ alias request_without_samuel request
+ def request(req, body = nil, &block)
+ Samuel.log_request(self, req) do
+ request_without_samuel(req, body, &block)
+ end
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel/request.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel/request.rb
new file mode 100644
index 000000000..e10ecb44e
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/lib/samuel/request.rb
@@ -0,0 +1,96 @@
+module Samuel
+ class Request
+
+ attr_accessor :response
+
+ def initialize(http, request, proc)
+ @http, @request, @proc = http, request, proc
+ end
+
+ def perform_and_log!
+ # If an exception is raised in the Benchmark block, it'll interrupt the
+ # benchmark. Instead, use an inner block to record it as the "response"
+ # for raising after the benchmark (and logging) is done.
+ @seconds = Benchmark.realtime do
+ begin; @response = @proc.call; rescue Exception => @response; end
+ end
+ Samuel.logger.add(log_level, log_message)
+ raise @response if @response.is_a?(Exception)
+ end
+
+ private
+
+ def log_message
+ bold = "\e[1m"
+ blue = "\e[34m"
+ underline = "\e[4m"
+ reset = "\e[0m"
+ " #{bold}#{blue}#{underline}#{label} request (#{milliseconds}ms) " +
+ "#{response_summary}#{reset} #{method} #{uri}"
+ end
+
+ def milliseconds
+ (@seconds * 1000).round
+ end
+
+ def uri
+ "#{scheme}://#{@http.address}#{port_if_not_default}#{filtered_path}"
+ end
+
+ def filtered_path
+ path_without_query, query = @request.path.split("?")
+ if query
+ patterns = [Samuel.config[:filtered_params]].flatten
+ patterns.map { |pattern|
+ pattern_for_regex = Regexp.escape(pattern.to_s)
+ [/([^&]*#{pattern_for_regex}[^&=]*)=(?:[^&]+)/, '\1=[FILTERED]']
+ }.each { |filter| query.gsub!(*filter) }
+ "#{path_without_query}?#{query}"
+ else
+ @request.path
+ end
+ end
+
+ def scheme
+ @http.use_ssl? ? "https" : "http"
+ end
+
+ def port_if_not_default
+ ssl, port = @http.use_ssl?, @http.port
+ if (!ssl && port == 80) || (ssl && port == 443)
+ ""
+ else
+ ":#{port}"
+ end
+ end
+
+ def method
+ @request.method.to_s.upcase
+ end
+
+ def label
+ return Samuel.config[:label] if Samuel.config[:label]
+
+ pair = Samuel.config[:labels].detect { |domain, label| @http.address.include?(domain) }
+ pair[1] if pair
+ end
+
+ def response_summary
+ if response.is_a?(Exception)
+ response.class
+ else
+ "[#{response.code} #{response.message}]"
+ end
+ end
+
+ def log_level
+ error_classes = [Exception, Net::HTTPClientError, Net::HTTPServerError]
+ if error_classes.any? { |klass| response.is_a?(klass) }
+ level = Logger::WARN
+ else
+ level = Logger::INFO
+ end
+ end
+
+ end
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/samuel.gemspec b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/samuel.gemspec
new file mode 100644
index 000000000..3a3719bf8
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/samuel.gemspec
@@ -0,0 +1,69 @@
+# Generated by jeweler
+# DO NOT EDIT THIS FILE
+# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
+ s.name = %q{samuel}
+ s.version = "0.2.1"
+
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+ s.authors = ["Chris Kampmeier"]
+ s.date = %q{2009-09-15}
+ s.description = %q{An automatic logger for HTTP requests in Ruby. Adds Net::HTTP request logging to your Rails logs, and more.}
+ s.email = %q{chris@kampers.net}
+ s.extra_rdoc_files = [
+ "LICENSE",
+ "README.rdoc"
+ ]
+ s.files = [
+ ".document",
+ ".gitignore",
+ "LICENSE",
+ "README.rdoc",
+ "Rakefile",
+ "VERSION",
+ "lib/samuel.rb",
+ "lib/samuel/net_http.rb",
+ "lib/samuel/request.rb",
+ "samuel.gemspec",
+ "test/request_test.rb",
+ "test/samuel_test.rb",
+ "test/test_helper.rb",
+ "test/thread_test.rb"
+ ]
+ s.homepage = %q{http://github.com/chrisk/samuel}
+ s.rdoc_options = ["--charset=UTF-8"]
+ s.require_paths = ["lib"]
+ s.rubyforge_project = %q{samuel}
+ s.rubygems_version = %q{1.3.5}
+ s.summary = %q{An automatic logger for HTTP requests in Ruby}
+ s.test_files = [
+ "test/request_test.rb",
+ "test/samuel_test.rb",
+ "test/test_helper.rb",
+ "test/thread_test.rb"
+ ]
+
+ if s.respond_to? :specification_version then
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ s.specification_version = 3
+
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
+ s.add_development_dependency(%q<yard>, [">= 0"])
+ s.add_development_dependency(%q<mocha>, [">= 0"])
+ s.add_development_dependency(%q<fakeweb>, [">= 0"])
+ else
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
+ s.add_dependency(%q<yard>, [">= 0"])
+ s.add_dependency(%q<mocha>, [">= 0"])
+ s.add_dependency(%q<fakeweb>, [">= 0"])
+ end
+ else
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
+ s.add_dependency(%q<yard>, [">= 0"])
+ s.add_dependency(%q<mocha>, [">= 0"])
+ s.add_dependency(%q<fakeweb>, [">= 0"])
+ end
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/request_test.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/request_test.rb
new file mode 100644
index 000000000..4e905d1ec
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/request_test.rb
@@ -0,0 +1,193 @@
+require 'test_helper'
+
+class RequestTest < Test::Unit::TestCase
+
+ context "making an HTTP request" do
+ setup { setup_test_logger
+ FakeWeb.clean_registry
+ Samuel.reset_config }
+ teardown { teardown_test_logger }
+
+ context "to GET http://example.com/test, responding with a 200 in 53ms" do
+ setup do
+ FakeWeb.register_uri(:get, "http://example.com/test", :status => [200, "OK"])
+ Benchmark.stubs(:realtime).yields.returns(0.053)
+ open "http://example.com/test"
+ end
+
+ should_log_lines 1
+ should_log_at_level :info
+ should_log_including "HTTP request"
+ should_log_including "(53ms)"
+ should_log_including "[200 OK]"
+ should_log_including "GET http://example.com/test"
+ end
+
+ context "on a non-standard port" do
+ setup do
+ FakeWeb.register_uri(:get, "http://example.com:8080/test", :status => [200, "OK"])
+ open "http://example.com:8080/test"
+ end
+
+ should_log_including "GET http://example.com:8080/test"
+ end
+
+ context "with SSL" do
+ setup do
+ FakeWeb.register_uri(:get, "https://example.com/test", :status => [200, "OK"])
+ open "https://example.com/test"
+ end
+
+ should_log_including "HTTP request"
+ should_log_including "GET https://example.com/test"
+ end
+
+ context "with SSL on a non-standard port" do
+ setup do
+ FakeWeb.register_uri(:get, "https://example.com:80/test", :status => [200, "OK"])
+ open "https://example.com:80/test"
+ end
+
+ should_log_including "HTTP request"
+ should_log_including "GET https://example.com:80/test"
+ end
+
+ context "that raises" do
+ setup do
+ FakeWeb.register_uri(:get, "http://example.com/test", :exception => Errno::ECONNREFUSED)
+ begin
+ Net::HTTP.start("example.com") { |http| http.get("/test") }
+ rescue Errno::ECONNREFUSED => @exception
+ end
+ end
+
+ should_log_at_level :warn
+ should_log_including "HTTP request"
+ should_log_including "GET http://example.com/test"
+ should_log_including "Errno::ECONNREFUSED"
+ should_log_including %r|\d+ms|
+ should_raise_exception Errno::ECONNREFUSED
+ end
+
+ context "that responds with a 500-level code" do
+ setup do
+ FakeWeb.register_uri(:get, "http://example.com/test", :status => [502, "Bad Gateway"])
+ Net::HTTP.start("example.com") { |http| http.get("/test") }
+ end
+
+ should_log_at_level :warn
+ end
+
+ context "that responds with a 400-level code" do
+ setup do
+ FakeWeb.register_uri(:get, "http://example.com/test", :status => [404, "Not Found"])
+ Net::HTTP.start("example.com") { |http| http.get("/test") }
+ end
+
+ should_log_at_level :warn
+ end
+
+ context "inside a configuration block with :label => 'Example'" do
+ setup do
+ FakeWeb.register_uri(:get, "http://example.com/test", :status => [200, "OK"])
+ Samuel.with_config :label => "Example" do
+ open "http://example.com/test"
+ end
+ end
+
+ should_log_including "Example request"
+ should_have_config_afterwards_including :labels => {"" => "HTTP"},
+ :label => nil
+ end
+
+ context "inside a configuration block with :filter_params" do
+ setup do
+ FakeWeb.register_uri(:get, "http://example.com/test?password=secret&username=chrisk",
+ :status => [200, "OK"])
+ @uri = "http://example.com/test?password=secret&username=chrisk"
+ end
+
+ context "=> :password" do
+ setup { Samuel.with_config(:filtered_params => :password) { open @uri } }
+ should_log_including "http://example.com/test?password=[FILTERED]&username=chrisk"
+ end
+
+ context "=> :as" do
+ setup { Samuel.with_config(:filtered_params => :ass) { open @uri } }
+ should_log_including "http://example.com/test?password=[FILTERED]&username=chrisk"
+ end
+
+ context "=> ['pass', 'name']" do
+ setup { Samuel.with_config(:filtered_params => %w(pass name)) { open @uri } }
+ should_log_including "http://example.com/test?password=[FILTERED]&username=[FILTERED]"
+ end
+ end
+
+ context "with a global config including :label => 'Example'" do
+ setup do
+ FakeWeb.register_uri(:get, "http://example.com/test", :status => [200, "OK"])
+ Samuel.config[:label] = "Example"
+ open "http://example.com/test"
+ end
+
+ should_log_including "Example request"
+ should_have_config_afterwards_including :labels => {"" => "HTTP"},
+ :label => "Example"
+ end
+
+ context "with a global config including :label => 'Example' but inside config block that changes it to 'Example 2'" do
+ setup do
+ FakeWeb.register_uri(:get, "http://example.com/test", :status => [200, "OK"])
+ Samuel.config[:label] = "Example"
+ Samuel.with_config(:label => "Example 2") { open "http://example.com/test" }
+ end
+
+ should_log_including "Example 2 request"
+ should_have_config_afterwards_including :labels => {"" => "HTTP"},
+ :label => "Example"
+ end
+
+ context "inside a config block of :label => 'Example 2' nested inside a config block of :label => 'Example'" do
+ setup do
+ FakeWeb.register_uri(:get, "http://example.com/test", :status => [200, "OK"])
+ Samuel.with_config :label => "Example" do
+ Samuel.with_config :label => "Example 2" do
+ open "http://example.com/test"
+ end
+ end
+ end
+
+ should_log_including "Example 2 request"
+ should_have_config_afterwards_including :labels => {"" => "HTTP"},
+ :label => nil
+ end
+
+ context "wth a global config including :labels => {'example.com' => 'Example'} but inside a config block of :label => 'Example 3' nested inside a config block of :label => 'Example 2'" do
+ setup do
+ FakeWeb.register_uri(:get, "http://example.com/test", :status => [200, "OK"])
+ Samuel.config[:labels] = {'example.com' => 'Example'}
+ Samuel.with_config :label => "Example 2" do
+ Samuel.with_config :label => "Example 3" do
+ open "http://example.com/test"
+ end
+ end
+ end
+
+ should_log_including "Example 3 request"
+ should_have_config_afterwards_including :labels => {'example.com' => 'Example'},
+ :label => nil
+ end
+
+ context "with a global config including :labels => {'example.com' => 'Example API'}" do
+ setup do
+ FakeWeb.register_uri(:get, "http://example.com/test", :status => [200, "OK"])
+ Samuel.config[:labels] = {'example.com' => 'Example API'}
+ open "http://example.com/test"
+ end
+
+ should_log_including "Example API request"
+ end
+
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/samuel_test.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/samuel_test.rb
new file mode 100644
index 000000000..4a3665fa6
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/samuel_test.rb
@@ -0,0 +1,42 @@
+require 'test_helper'
+
+class SamuelTest < Test::Unit::TestCase
+
+ context "logger configuration" do
+ setup do
+ Samuel.logger = nil
+ if Object.const_defined?(:RAILS_DEFAULT_LOGGER)
+ Object.send(:remove_const, :RAILS_DEFAULT_LOGGER)
+ end
+ end
+
+ teardown do
+ Samuel.logger = nil
+ end
+
+ context "when Rails's logger is available" do
+ setup { Object.const_set(:RAILS_DEFAULT_LOGGER, :mock_logger) }
+
+ should "use the same logger" do
+ assert_equal :mock_logger, Samuel.logger
+ end
+ end
+
+ context "when Rails's logger is not available" do
+ should "use a new Logger instance pointed to STDOUT" do
+ assert_instance_of Logger, Samuel.logger
+ assert_equal STDOUT, Samuel.logger.instance_variable_get(:"@logdev").dev
+ end
+ end
+ end
+
+
+ context ".reset_config" do
+ should "reset the config to default vaules" do
+ Samuel.config = {:foo => "bar"}
+ Samuel.reset_config
+ assert_equal({:label => nil, :labels => {"" => "HTTP"}, :filtered_params => []}, Samuel.config)
+ end
+ end
+
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/test_helper.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/test_helper.rb
new file mode 100644
index 000000000..2862051b9
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/test_helper.rb
@@ -0,0 +1,66 @@
+require 'rubygems'
+require 'test/unit'
+require 'shoulda'
+require 'mocha'
+require 'open-uri'
+require 'fakeweb'
+
+FakeWeb.allow_net_connect = false
+
+$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
+$LOAD_PATH.unshift(File.dirname(__FILE__))
+require 'samuel'
+
+class Test::Unit::TestCase
+ TEST_LOG_PATH = File.join(File.dirname(__FILE__), 'test.log')
+
+ def self.should_log_lines(expected_count)
+ should "log #{expected_count} line#{'s' unless expected_count == 1}" do
+ lines = File.readlines(TEST_LOG_PATH)
+ assert_equal expected_count, lines.length
+ end
+ end
+
+ def self.should_log_including(what)
+ should "log a line including #{what.inspect}" do
+ contents = File.read(TEST_LOG_PATH)
+ if what.is_a?(Regexp)
+ assert_match what, contents
+ else
+ assert contents.include?(what),
+ "Expected #{contents.inspect} to include #{what.inspect}"
+ end
+ end
+ end
+
+ def self.should_log_at_level(level)
+ level = level.to_s.upcase
+ should "log at the #{level} level" do
+ assert File.read(TEST_LOG_PATH).include?(" #{level} -- :")
+ end
+ end
+
+ def self.should_raise_exception(klass)
+ should "raise an #{klass} exception" do
+ assert @exception.is_a?(klass)
+ end
+ end
+
+ def self.should_have_config_afterwards_including(config)
+ config.each_pair do |key, value|
+ should "continue afterwards with Samuel.config[#{key.inspect}] set to #{value.inspect}" do
+ assert_equal value, Samuel.config[key]
+ end
+ end
+ end
+
+ def setup_test_logger
+ FileUtils.rm_rf TEST_LOG_PATH
+ FileUtils.touch TEST_LOG_PATH
+ Samuel.logger = Logger.new(TEST_LOG_PATH)
+ end
+
+ def teardown_test_logger
+ FileUtils.rm_rf TEST_LOG_PATH
+ end
+end
diff --git a/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/thread_test.rb b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/thread_test.rb
new file mode 100644
index 000000000..d030cb973
--- /dev/null
+++ b/vendor/gems/fakeweb-1.3.0/test/vendor/samuel-0.2.1/test/thread_test.rb
@@ -0,0 +1,32 @@
+require 'test_helper'
+
+class ThreadTest < Test::Unit::TestCase
+
+ context "when logging multiple requests at once" do
+ setup do
+ @log = StringIO.new
+ Samuel.logger = Logger.new(@log)
+ FakeWeb.register_uri(:get, /example\.com/, :status => [200, "OK"])
+ threads = []
+ 5.times do |i|
+ threads << Thread.new(i) do |n|
+ Samuel.with_config :label => "Example #{n}" do
+ Thread.pass
+ open "http://example.com/#{n}"
+ end
+ end
+ end
+ threads.each { |t| t.join }
+ @log.rewind
+ end
+
+ should "not let configuration blocks interfere with eachother" do
+ @log.each_line do |line|
+ matches = %r|Example (\d+).*example\.com/(\d+)|.match(line)
+ assert_not_nil matches
+ assert_equal matches[1], matches[2]
+ end
+ end
+ end
+
+end