Skip to content
View
1 lib/webmock.rb
@@ -14,6 +14,7 @@
require 'webmock/http_lib_adapters/curb_adapter'
require 'webmock/http_lib_adapters/em_http_request_adapter'
require 'webmock/http_lib_adapters/typhoeus_hydra_adapter'
+require 'webmock/http_lib_adapters/excon_adapter'
require 'webmock/errors'
View
77 lib/webmock/http_lib_adapters/excon_adapter.rb
@@ -0,0 +1,77 @@
+begin
+ require 'excon'
+rescue LoadError
+ # excon not found
+end
+
+if defined?(Excon)
+
+ module WebMock
+ module HttpLibAdapters
+
+ class ExconAdapter < HttpLibAdapter
+ adapter_for :excon
+
+ def self.enable!
+ Excon.send(:remove_const, :Connection)
+ Excon.send(:const_set, :Connection, ExconConnection)
+ end
+
+ def self.disable!
+ Excon.send(:remove_const, :Connection)
+ Excon.send(:const_set, :Connection, ExconConnection.superclass)
+ end
+
+ def self.build_request(params)
+ uri = Addressable::URI.new(params).to_s
+ method = (params[:method] || :get).to_s.downcase.to_sym
+ WebMock::RequestSignature.new method, uri, :body => params[:body], :headers => params[:headers]
+ end
+
+ def self.real_response(mock)
+ raise Excon::Errors::Timeout if mock.should_timeout
+ mock.raise_error_if_any
+ Excon::Response.new \
+ :body => mock.body,
+ :status => mock.status[0].to_i,
+ :headers => mock.headers
+ end
+
+ def self.mock_response(real)
+ mock = WebMock::Response.new
+ mock.status = real.status
+ mock.headers = real.headers
+ mock.body = real.body
+ mock
+ end
+
+ def self.perform_callbacks(request, response, options = {})
+ return unless WebMock::CallbackRegistry.any_callbacks?
+ WebMock::CallbackRegistry.invoke_callbacks(options.merge(:lib => :excon), request, response)
+ end
+
+ end
+
+ class ExconConnection < ::Excon::Connection
+
+ def request_kernel(params, &block)
+ mock_request = ExconAdapter.build_request params.dup
+ WebMock::RequestRegistry.instance.requested_signatures.put(mock_request)
+
+ if mock_response = WebMock::StubRegistry.instance.response_for_request(mock_request)
+ ExconAdapter.perform_callbacks(mock_request, mock_response, :real_request => false)
+ ExconAdapter.real_response(mock_response)
+ elsif WebMock.net_connect_allowed?(mock_request.uri)
+ real_response = super
+ ExconAdapter.perform_callbacks(mock_request, ExconAdapter.mock_response(real_response), :real_request => true)
+ real_response
+ else
+ raise WebMock::NetConnectNotAllowedError.new(mock_request)
+ end
+ end
+
+ end
+ end
+ end
+
+end
View
9 spec/acceptance/excon/excon_spec.rb
@@ -0,0 +1,9 @@
+require 'spec_helper'
+require 'acceptance/webmock_shared'
+require 'acceptance/excon/excon_spec_helper'
+
+describe "Excon" do
+ include ExconSpecHelper
+ include_context "with WebMock"
+end
+
View
37 spec/acceptance/excon/excon_spec_helper.rb
@@ -0,0 +1,37 @@
+require 'ostruct'
+
+module ExconSpecHelper
+
+ def http_request(method, uri, options = {}, &block)
+ uri = Addressable::URI.heuristic_parse(uri)
+ uri = uri.omit(:userinfo).to_s.gsub(' ', '+')
+
+ options = options.merge(:method => method) # Dup and merge
+ response = Excon.new(uri).request(options, &block)
+
+ headers = WebMock::Util::Headers.normalize_headers(response.headers)
+ headers = headers.inject({}) do |res, (name, value)|
+ res[name] = value.is_a?(Array) ? value.flatten.join(', ') : value
+ res
+ end
+
+ OpenStruct.new \
+ :body => response.body,
+ :headers => headers,
+ :status => response.status.to_s,
+ :message => ""
+ end
+
+ def client_timeout_exception_class
+ Excon::Errors::Timeout
+ end
+
+ def connection_refused_exception_class
+ Excon::Errors::SocketError
+ end
+
+ def http_library
+ :excon
+ end
+
+end
View
3 spec/acceptance/shared/callbacks.rb
@@ -87,7 +87,8 @@
it "should pass real response to callback with status and message" do
# not supported by em-http-request, it always returns "unknown" for http_reason
- unless http_library == :em_http_request
+ # not supported by excon, it only returns a status code
+ unless [:em_http_request, :excon].include?(http_library)
@response.status[0].should == 302
@response.status[1].should == "Found"
end
View
1 spec/acceptance/shared/request_expectations.rb
@@ -412,6 +412,7 @@
describe "with authentication" do
before(:each) do
+ pending "Excon does not accept basic auth user-info in URLs" if http_library == :excon
stub_request(:any, "http://user:pass@www.example.com")
stub_request(:any, "http://user:pazz@www.example.com")
end
View
12 spec/acceptance/shared/returning_declared_responses.rb
@@ -76,7 +76,8 @@ class MyException < StandardError; end;
stub_request(:get, "www.example.com").to_return(:status => [500, "Internal Server Error"])
response = http_request(:get, "http://www.example.com/")
# not supported by em-http-request, it always returns "unknown" for http_reason
- unless http_library == :em_http_request
+ # not supported by excon, it only returns a status code
+ unless [:em_http_request, :excon].include?(http_library)
response.message.should == "Internal Server Error"
end
end
@@ -90,7 +91,8 @@ class MyException < StandardError; end;
stub_request(:get, "www.example.com")
response = http_request(:get, "http://www.example.com/")
# not supported by em-http-request, it always returns "unknown" for http_reason
- unless http_library == :em_http_request
+ # not supported by excon, it only returns a status code
+ unless [:em_http_request, :excon].include?(http_library)
response.message.should == ""
end
end
@@ -188,7 +190,8 @@ def call(request)
it "should return recorded status message" do
# not supported by em-http-request, it always returns "unknown" for http_reason
- unless http_library == :em_http_request
+ # not supported by excon, it only returns a status code
+ unless [:em_http_request, :excon].include?(http_library)
@response.message.should == "OK"
end
end
@@ -225,7 +228,8 @@ def call(request)
it "should return recorded status message" do
# not supported by em-http-request, it always returns "unknown" for http_reason
- unless http_library == :em_http_request
+ # not supported by excon, it only returns a status code
+ unless [:em_http_request, :excon].include?(http_library)
@response.message.should == "OK"
end
end
View
4 spec/acceptance/shared/stubbing_requests.rb
@@ -260,6 +260,10 @@
end
describe "when stubbing request with basic authentication" do
+ before do
+ pending "Excon does not accept basic auth user-info in URLs" if http_library == :excon
+ end
+
it "should match if credentials are the same" do
stub_request(:get, "user:pass@www.example.com")
http_request(:get, "http://user:pass@www.example.com/").status.should == "200"
View
1 webmock.gemspec
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
s.add_development_dependency 'em-synchrony', '>= 1.0.0' if RUBY_VERSION >= "1.9"
s.add_development_dependency 'curb', '>= 0.8.0'
s.add_development_dependency 'typhoeus', '>= 0.3.0' unless RUBY_PLATFORM =~ /java/
+ s.add_development_dependency 'excon', '>= 0.9.5'
s.add_development_dependency 'minitest', '>= 2.2.2'
s.add_development_dependency 'rdoc', ((RUBY_VERSION == '1.8.6') ? '<= 3.5.0' : '>3.5.0')

0 comments on commit e2369ac

Please sign in to comment.
Something went wrong with that request. Please try again.