Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Typhoeus 0.5.0 #212

Merged
merged 14 commits into from

3 participants

@i0rek

This PR makes webmock work with the upcoming typhoeus release. One of the interesting things is, that the monkey patch is gone.

One thing that still needs to be addressed is that there is now more than one way to do a request. request.run no longer uses the hydra. Basically all tests must be run with hydra.run and request.run. The reason I'm not extremely concerned that everything breaks for request.run is that the before hook is quite simple and do exist for both of course.

@bblimke
Owner

Awesome, no monkey patching! Can't wait to merge it :)

@i0rek

I think what @myronmarston said about vcr applies here too: i0rek/vcr@84fb704#commitcomment-1928493.

The with_connection block shouldn't be there.

Collaborator

I updated VCR based on typhoeus/typhoeus@0caa30b so that VCR now sets request.block_connection = false on individual requests rather than wrapping them in with_connection at the point the request is made, and that worked...but I started getting failures from the webmock specs when using typhoeus because the client still has to use with_connection when using typhoeus with WebMock as demonstrated here. I can't get a green VCR build until this is fixed.

I'll take care of that. Thanks for your effort!

@i0rek

Done! All green.

@myronmarston
Collaborator

@i0rek -- Thanks, I'll take a stab at integrating your work into VCR master this week.

@bblimke bblimke merged commit 720f151 into bblimke:master
@bblimke
Owner

@i0rek awesome. congrats! I just released WebMock 1.9.0 with your pull request merged in. Cheers.

@i0rek
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
1  Gemfile
@@ -10,6 +10,7 @@ group :development do
gem 'rake'
gem 'guard-rspec'
gem 'rb-fsevent'
+ gem "typhoeus", git: "git@github.com:typhoeus/typhoeus.git"
end
group :test do
View
130 lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb
@@ -14,53 +14,56 @@ class TyphoeusAdapter < HttpLibAdapter
def self.enable!
@disabled = false
+ add_before_callback
add_after_request_callback
- ::Typhoeus::Hydra.allow_net_connect = true
+ ::Typhoeus::Config.block_connection = true
end
def self.disable!
@disabled = true
remove_after_request_callback
- ::Typhoeus::Hydra.allow_net_connect = true
+ remove_before_callback
+ ::Typhoeus::Config.block_connection = false
end
def self.disabled?
!!@disabled
end
+ def self.add_before_callback
+ unless Typhoeus.before.include?(BEFORE_CALLBACK)
+ Typhoeus.before << BEFORE_CALLBACK
+ end
+ end
+
+ def self.remove_before_callback
+ Typhoeus.before.delete_if {|v| v == BEFORE_CALLBACK }
+ end
+
def self.add_after_request_callback
- unless Typhoeus::Hydra.
- global_hooks[:after_request_before_on_complete].
- include?(AFTER_REQUEST_CALLBACK)
- Typhoeus::Hydra.
- global_hooks[:after_request_before_on_complete] << AFTER_REQUEST_CALLBACK
+ unless Typhoeus.on_complete.include?(AFTER_REQUEST_CALLBACK)
+ Typhoeus.on_complete << AFTER_REQUEST_CALLBACK
end
end
def self.remove_after_request_callback
- Typhoeus::Hydra.global_hooks[:after_request_before_on_complete].
- delete_if {|v| v == AFTER_REQUEST_CALLBACK }
+ Typhoeus.on_complete.delete_if {|v| v == AFTER_REQUEST_CALLBACK }
end
def self.build_request_signature(req)
uri = WebMock::Util::URI.heuristic_parse(req.url)
uri.path = uri.normalized_path.gsub("[^:]//","/")
- if req.username
- uri.user = req.username
- uri.password = req.password
+ if req.options[:userpwd]
+ uri.user, uri.password = req.options[:userpwd].split(':')
end
- body = req.body
-
- if req.params && req.method == :post
- body = request_body_for_post_request_with_params(req)
- end
+ body = req.options[:body]
request_signature = WebMock::RequestSignature.new(
- req.method,
+ req.options[:method],
uri.to_s,
:body => body,
- :headers => req.headers
+ :headers => req.options[:headers]
)
req.instance_variable_set(:@__webmock_request_signature, request_signature)
@@ -68,45 +71,33 @@ def self.build_request_signature(req)
request_signature
end
- def self.request_body_for_post_request_with_params(req)
- params = req.params
- form = Typhoeus::Form.new(params)
- form.process!
- form.to_s
- end
-
def self.build_webmock_response(typhoeus_response)
webmock_response = WebMock::Response.new
webmock_response.status = [typhoeus_response.code, typhoeus_response.status_message]
webmock_response.body = typhoeus_response.body
- webmock_response.headers = typhoeus_response.headers_hash
+ webmock_response.headers = typhoeus_response.headers
webmock_response
end
- def self.stub_typhoeus(request_signature, webmock_response, typhoeus)
+ def self.generate_typhoeus_response(request_signature, webmock_response)
response = if webmock_response.should_timeout
::Typhoeus::Response.new(
:code => 0,
:status_message => "",
:body => "",
- :headers_hash => {},
- :curl_return_code => 28
+ :headers => {},
+ :return_code => :operation_timedout
)
else
::Typhoeus::Response.new(
:code => webmock_response.status[0],
:status_message => webmock_response.status[1],
:body => webmock_response.body,
- :headers_hash => webmock_response.headers
+ :headers => webmock_response.headers
)
end
-
-
- typhoeus.stub(
- request_signature.method || :any,
- /.*/,
- :webmock_stub => true
- ).and_return(response)
+ response.mock = :webmock
+ response
end
def self.request_hash(request_signature)
@@ -118,12 +109,13 @@ def self.request_hash(request_signature)
hash
end
- AFTER_REQUEST_CALLBACK = Proc.new do |request|
+ AFTER_REQUEST_CALLBACK = Proc.new do |response|
+ request = response.request
request_signature = request.instance_variable_get(:@__webmock_request_signature)
webmock_response =
::WebMock::HttpLibAdapters::TyphoeusAdapter.
- build_webmock_response(request.response)
- if request.response.mock?
+ build_webmock_response(response)
+ if response.mock
WebMock::CallbackRegistry.invoke_callbacks(
{:lib => :typhoeus},
request_signature,
@@ -137,43 +129,29 @@ def self.request_hash(request_signature)
)
end
end
- end
- end
- end
-
-
- module Typhoeus
- class Hydra
- def queue_with_webmock(request)
- self.clear_webmock_stubs
-
- if WebMock::HttpLibAdapters::TyphoeusAdapter.disabled?
- return queue_without_webmock(request)
- end
- request_signature =
- ::WebMock::HttpLibAdapters::TyphoeusAdapter.build_request_signature(request)
-
- ::WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
-
- if webmock_response = ::WebMock::StubRegistry.instance.response_for_request(request_signature)
- ::WebMock::HttpLibAdapters::TyphoeusAdapter.
- stub_typhoeus(request_signature, webmock_response, self)
- webmock_response.raise_error_if_any
- elsif !WebMock.net_connect_allowed?(request_signature.uri)
- raise WebMock::NetConnectNotAllowedError.new(request_signature)
+ BEFORE_CALLBACK = Proc.new do |request|
+ Typhoeus::Expectation.all.delete_if {|e| e.from == :webmock }
+ res = true
+
+ unless WebMock::HttpLibAdapters::TyphoeusAdapter.disabled?
+ request_signature = ::WebMock::HttpLibAdapters::TyphoeusAdapter.build_request_signature(request)
+ request.block_connection = false;
+
+ ::WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
+
+ if webmock_response = ::WebMock::StubRegistry.instance.response_for_request(request_signature)
+ # ::WebMock::HttpLibAdapters::TyphoeusAdapter.stub_typhoeus(request_signature, webmock_response, self)
+ response = ::WebMock::HttpLibAdapters::TyphoeusAdapter.generate_typhoeus_response(request_signature, webmock_response)
+ request.finish(response)
+ webmock_response.raise_error_if_any
+ res = false
+ elsif !WebMock.net_connect_allowed?(request_signature.uri)
+ raise WebMock::NetConnectNotAllowedError.new(request_signature)
+ end
+ end
+ res
end
- queue_without_webmock(request)
- end
-
- alias_method :queue_without_webmock, :queue
- alias_method :queue, :queue_with_webmock
-
- def clear_webmock_stubs
- self.stubs = [] unless self.stubs
- self.stubs.delete_if {|s|
- s.instance_variable_get(:@options)[:webmock_stub]
- }
end
end
end
View
36 spec/acceptance/typhoeus/typhoeus_hydra_spec.rb
@@ -6,6 +6,11 @@
describe "Typhoeus::Hydra" do
include TyphoeusHydraSpecHelper
+ let(:hydra) { Typhoeus::Hydra.new }
+
+ before do
+ Typhoeus::Expectation.clear
+ end
include_context "with WebMock"
@@ -17,13 +22,17 @@
describe "when params are used" do
it "should take into account params for POST request" do
- stub_request(:post, "www.example.com").with(:body => {:hello => 'world'})
- Typhoeus::Request.post("www.example.com", :params => {:hello => 'world'})
+ stub_request(:post, "www.example.com").with(:params => {:hello => 'world'})
+ request = Typhoeus::Request.new("http://www.example.com", :method => :post, :params => {:hello => 'world'})
+ hydra.queue(request)
+ hydra.run
end
it "should take into account params for GET request" do
- stub_request(:get, "http://www.example.com/?hello=world")
- Typhoeus::Request.get("www.example.com", :params => {:hello => 'world'})
+ stub_request(:get, "http://www.example.com/?hello=world").to_return({})
+ request = Typhoeus::Request.new("http://www.example.com/?hello=world", :method => :get)
+ hydra.queue(request)
+ hydra.run
end
end
@@ -31,15 +40,16 @@
it "should support native typhoeus timeouts" do
stub_request(:any, "example.com").to_timeout
- response = Typhoeus::Request.get("http://example.com")
+ request = Typhoeus::Request.new("http://example.com", :method => :get)
+ hydra.queue(request)
+ hydra.run
- response.should be_timed_out
+ request.response.should be_timed_out
end
end
describe "callbacks" do
before(:each) do
- @hydra = Typhoeus::Hydra.new
@request = Typhoeus::Request.new("http://example.com")
end
@@ -48,11 +58,11 @@
stub_request(:any, "example.com").to_return(:body => body)
test = nil
- @hydra.on_complete do |c|
+ Typhoeus.on_complete do |c|
test = c.body
end
- @hydra.queue @request
- @hydra.run
+ hydra.queue @request
+ hydra.run
test.should == body
end
@@ -61,11 +71,11 @@
stub_request(:any, "example.com").to_return(:status => [response_code, "Server On Fire"])
test = nil
- @hydra.on_complete do |c|
+ Typhoeus.on_complete do |c|
test = c.code
end
- @hydra.queue @request
- @hydra.run
+ hydra.queue @request
+ hydra.run
test.should == response_code
end
end
View
7 spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb
@@ -15,15 +15,16 @@ def http_request(method, uri, options = {}, &block)
:timeout => 25000
}
)
- hydra = Typhoeus::Hydra.new(:initial_pool_size => 0)
+ hydra = Typhoeus::Hydra.new
hydra.queue(request)
hydra.run
+
response = request.response
+ raise FakeTyphoeusHydraConnectError.new if response.return_code == :couldnt_connect
raise FakeTyphoeusHydraTimeoutError.new if response.timed_out?
- raise FakeTyphoeusHydraConnectError.new if response.code == 0
OpenStruct.new({
:body => response.body,
- :headers => WebMock::Util::Headers.normalize_headers(join_array_values(response.headers_hash)),
+ :headers => WebMock::Util::Headers.normalize_headers(join_array_values(response.headers)),
:status => response.code.to_s,
:message => response.status_message
})
Something went wrong with that request. Please try again.