Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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.