Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Changed ExconAdapter to use Excon's mock middleware and made it compa…

…tible with Excon >= 0.17
  • Loading branch information...
commit 3639da1a1c8bbc067a546dc2708c5a759de9b660 1 parent 5268fac
@bblimke authored
View
117 lib/webmock/http_lib_adapters/excon_adapter.rb
@@ -11,18 +11,67 @@ module WebMock
module HttpLibAdapters
class ExconAdapter < HttpLibAdapter
+ PARAMS_TO_DELETE = [:expects, :idempotent,
+ :instrumentor_name, :instrumentor,
+ :response_block, :request_block,
+ :__construction_args, :stack,
+ :connection, :response]
+
adapter_for :excon
def self.enable!
- Excon.send(:remove_const, :Connection)
- Excon.send(:const_set, :Connection, ExconConnection)
+ self.add_excon_stub
end
def self.disable!
- Excon.send(:remove_const, :Connection)
- Excon.send(:const_set, :Connection, ExconConnection.superclass)
+ self.remove_excon_stub
+ end
+
+ def self.add_excon_stub
+ ::Excon.defaults[:mock] = true
+ @stub ||= ::Excon.stub({}) do |params|
+ self.handle_request(params)
+ end
+ end
+
+ def self.remove_excon_stub
+ ::Excon.defaults[:mock] = false
+ Excon.stubs.delete(@stub)
+ @stub = nil
+ end
+
+ def self.handle_request(params)
+ mock_request = self.build_request params.dup
+ WebMock::RequestRegistry.instance.requested_signatures.put(mock_request)
+
+ if mock_response = WebMock::StubRegistry.instance.response_for_request(mock_request)
+ self.perform_callbacks(mock_request, mock_response, :real_request => false)
+ response = self.real_response(mock_response)
+ response
+ elsif WebMock.net_connect_allowed?(mock_request.uri)
+ conn = new_excon_connection(params)
+ real_response = conn.request(scrub_params_from(params.merge(:mock => false)))
+
+ ExconAdapter.perform_callbacks(mock_request, ExconAdapter.mock_response(real_response), :real_request => true)
+
+ real_response.data
+ else
+ raise WebMock::NetConnectNotAllowedError.new(mock_request)
+ end
+ end
+
+ def self.new_excon_connection(params)
+ # Ensure the connection is constructed with the exact same args
+ # that the orginal connection was constructed with.
+ args = params.fetch(:__construction_args)
+ ::Excon::Connection.new(scrub_params_from args.merge(:mock => false))
end
+ def self.scrub_params_from(hash)
+ hash = hash.dup
+ PARAMS_TO_DELETE.each { |key| hash.delete(key) }
+ hash
+ end
def self.to_query(hash)
string = ""
@@ -58,17 +107,18 @@ def self.body_from(params)
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
+ :headers => mock.headers || {}
+ }
end
- def self.mock_response(real, response_body_from_chunks)
+ def self.mock_response(real)
mock = WebMock::Response.new
mock.status = real.status
mock.headers = real.headers
- mock.body = response_body_from_chunks || real.body
+ mock.body = real.body
mock
end
@@ -76,54 +126,15 @@ 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
+ end
+ end
- class ExconConnection < ::Excon::Connection
-
- def request_kernel(params)
- 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)
- response = ExconAdapter.real_response(mock_response)
-
- if params.has_key?(:expects) && ![*params[:expects]].include?(response.status)
- raise(Excon::Errors.status_error(params, response))
- elsif params.has_key?(:response_block)
- content_length = remaining = response.body.bytesize
- body = response.body
- response.body = ""
- i = 0
- while i < body.length
- params[:response_block].call(body[i, params[:chunk_size]], [remaining - params[:chunk_size], 0].max, content_length)
- remaining -= params[:chunk_size]
- i += params[:chunk_size]
- end
- end
- response
-
- elsif WebMock.net_connect_allowed?(mock_request.uri)
- response_body_from_chunks = nil
- if params.has_key?(:response_block)
- response_body_from_chunks = ""
- original_block = params[:response_block]
- params[:response_block] = lambda {|chunk, remaining, total|
- response_body_from_chunks << chunk
- original_block.call(chunk, remaining, total)
- }
- end
- real_response = super
- ExconAdapter.perform_callbacks(mock_request, ExconAdapter.mock_response(real_response, response_body_from_chunks), :real_request => true)
- real_response
- else
- raise WebMock::NetConnectNotAllowedError.new(mock_request)
- end
- end
-
+ Excon::Connection.class_eval do
+ def self.new(args)
+ super.tap do |instance|
+ instance.data[:__construction_args] = args
end
end
end
-
end
View
12 spec/acceptance/excon/excon_spec.rb
@@ -8,19 +8,19 @@
it 'should allow Excon requests to use query hash paramters' do
stub_request(:get, "http://example.com/resource/?a=1&b=2").to_return(:body => "abc")
- Excon.get('http://example.com', :path => "resource/", :query => {:a => 1, :b => 2}).body.should == "abc"
+ Excon.new('http://example.com').get(:path => "resource/", :query => {:a => 1, :b => 2}).body.should == "abc"
end
it 'should support Excon :expects options' do
stub_request(:get, "http://example.com/").to_return(:body => 'a')
- lambda { Excon.get('http://example.com', :expects => 204) }.should raise_error(Excon::Errors::OK)
+ lambda { Excon.new('http://example.com').get(:expects => 204) }.should raise_error(Excon::Errors::OK)
end
context "with response_block" do
it "should support excon response_block for real requests" do
a = []
WebMock.allow_net_connect!
- r = Excon.get('http://httpstat.us/200', :response_block => lambda {|e,remaining, total| a << e}, :chunk_size => 1)
+ r = Excon.new('http://httpstat.us/200').get(:response_block => lambda {|e, remaining, total| a << e}, :chunk_size => 1)
a.should == ["2", "0", "0", " ", "O", "K"]
r.body.should == ""
end
@@ -28,7 +28,7 @@
it "should support excon response_block" do
a = []
stub_request(:get, "http://example.com/").to_return(:body => "abc")
- r = Excon.get('http://example.com', :response_block => lambda {|e, remaining, total| a << e}, :chunk_size => 1)
+ r = Excon.new('http://example.com').get(:response_block => lambda {|e, remaining, total| a << e}, :chunk_size => 1)
a.should == ['a', 'b', 'c']
r.body.should == ""
end
@@ -40,7 +40,7 @@
WebMock.after_request { |_, res|
response = res
}
- r = Excon.get('http://httpstat.us/200', :response_block => lambda {|e,remaining, total| a << e}, :chunk_size => 1)
+ r = Excon.new('http://httpstat.us/200').get(:response_block => lambda {|e, remaining, total| a << e}, :chunk_size => 1)
response.body.should == "200 OK"
a.should == ["2", "0", "0", " ", "O", "K"]
r.body.should == ""
@@ -58,7 +58,7 @@
yielded_request_body = req.body
end
- Excon.put("http://example.com", :path => "upload", :body => file)
+ Excon.new("http://example.com").put(:path => "upload", :body => file)
yielded_request_body.should eq(file_contents)
end
Please sign in to comment.
Something went wrong with that request. Please try again.