Permalink
Browse files

Enabling and disabling http lib adapters uses constant replacement in…

…stead of conditional variable.
  • Loading branch information...
bblimke committed Aug 13, 2011
1 parent a972253 commit b3d60450e49e724a38a40d4f98fafdfed611ebd3
View
@@ -6,6 +6,8 @@
require 'webmock/deprecation'
require 'webmock/version'
+require 'webmock/http_lib_adapters/http_lib_adapter_registry'
+require 'webmock/http_lib_adapters/http_lib_adapter'
require 'webmock/http_lib_adapters/net_http'
require 'webmock/http_lib_adapters/httpclient'
require 'webmock/http_lib_adapters/patron'
View
@@ -6,6 +6,5 @@ class Config
attr_accessor :allow_localhost
attr_accessor :allow
attr_accessor :net_http_connect_on_start
- attr_accessor :disabled
end
end
@@ -0,0 +1,7 @@
+module WebMock
+ class HttpLibAdapter
+ def self.adapter_for(lib)
+ WebMock::HttpLibAdapterRegistry.instance.register(lib, self)
+ end
+ end
+end
@@ -0,0 +1,19 @@
+module WebMock
+ class HttpLibAdapterRegistry
+ include Singleton
+
+ attr_accessor :http_lib_adapters
+
+ def initialize
+ @http_lib_adapters = {}
+ end
+
+ def register(lib, adapter)
+ @http_lib_adapters[lib] = adapter
+ end
+
+ def each_adapter(&block)
+ @http_lib_adapters.values.each(&block)
+ end
+ end
+end
@@ -4,108 +4,121 @@
# patron not found
end
-if defined?(Patron)
-
- module Patron
- class Session
+if defined?(::Patron)
+ module WebMock
+ module HttpLibAdapters
+ class PatronAdapter < ::WebMock::HttpLibAdapter
+ adapter_for :patron
+
+ OriginalPatronSession = ::Patron::Session unless const_defined?(:OriginalPatronSession)
+
+ class WebMockPatronSession < ::Patron::Session
+ def handle_request_with_webmock(req)
+ request_signature =
+ WebMock::HttpLibAdapters::PatronAdapter.build_request_signature(req)
+
+ WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
+
+ if WebMock::StubRegistry.instance.registered_request?(request_signature)
+ webmock_response =
+ WebMock::StubRegistry.instance.response_for_request(request_signature)
+ WebMock::HttpLibAdapters::PatronAdapter.
+ handle_file_name(req, webmock_response)
+ res = WebMock::HttpLibAdapters::PatronAdapter.
+ build_patron_response(webmock_response)
+ WebMock::CallbackRegistry.invoke_callbacks(
+ {:lib => :patron}, request_signature, webmock_response)
+ res
+ elsif WebMock.net_connect_allowed?(request_signature.uri)
+ res = handle_request_without_webmock(req)
+ if WebMock::CallbackRegistry.any_callbacks?
+ webmock_response = WebMock::HttpLibAdapters::PatronAdapter.
+ build_webmock_response(res)
+ WebMock::CallbackRegistry.invoke_callbacks(
+ {:lib => :patron, :real_request => true}, request_signature,
+ webmock_response)
+ end
+ res
+ else
+ raise WebMock::NetConnectNotAllowedError.new(request_signature)
+ end
+ end
- def handle_request_with_webmock(req)
- if WebMock.disabled?
- return handle_request_without_webmock(req)
+ alias_method :handle_request_without_webmock, :handle_request
+ alias_method :handle_request, :handle_request_with_webmock
end
- request_signature = build_request_signature(req)
-
- WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
-
- if WebMock::StubRegistry.instance.registered_request?(request_signature)
- webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
- handle_file_name(req, webmock_response)
- res = build_patron_response(webmock_response)
- WebMock::CallbackRegistry.invoke_callbacks(
- {:lib => :patron}, request_signature, webmock_response)
- res
- elsif WebMock.net_connect_allowed?(request_signature.uri)
- res = handle_request_without_webmock(req)
- if WebMock::CallbackRegistry.any_callbacks?
- webmock_response = build_webmock_response(res)
- WebMock::CallbackRegistry.invoke_callbacks(
- {:lib => :patron, :real_request => true}, request_signature,
- webmock_response)
- end
- res
- else
- raise WebMock::NetConnectNotAllowedError.new(request_signature)
+ def self.enable!
+ Patron.send(:remove_const, :Session)
+ Patron.send(:const_set, :Session, WebMockPatronSession)
end
- end
-
- alias_method :handle_request_without_webmock, :handle_request
- alias_method :handle_request, :handle_request_with_webmock
-
+ def self.disable!
+ Patron.send(:remove_const, :Session)
+ Patron.send(:const_set, :Session, OriginalPatronSession)
+ end
- def handle_file_name(req, webmock_response)
- if req.action == :get && req.file_name
- begin
- File.open(req.file_name, "w") do |f|
- f.write webmock_response.body
+ def self.handle_file_name(req, webmock_response)
+ if req.action == :get && req.file_name
+ begin
+ File.open(req.file_name, "w") do |f|
+ f.write webmock_response.body
+ end
+ rescue Errno::EACCES
+ raise ArgumentError.new("Unable to open specified file.")
end
- rescue Errno::EACCES
- raise ArgumentError.new("Unable to open specified file.")
end
end
- end
-
- def build_request_signature(req)
- uri = WebMock::Util::URI.heuristic_parse(req.url)
- uri.path = uri.normalized_path.gsub("[^:]//","/")
- uri.user = req.username
- uri.password = req.password
- if [:put, :post].include?(req.action)
- if req.file_name
- if !File.exist?(req.file_name) || !File.readable?(req.file_name)
- raise ArgumentError.new("Unable to open specified file.")
+ def self.build_request_signature(req)
+ uri = WebMock::Util::URI.heuristic_parse(req.url)
+ uri.path = uri.normalized_path.gsub("[^:]//","/")
+ uri.user = req.username
+ uri.password = req.password
+
+ if [:put, :post].include?(req.action)
+ if req.file_name
+ if !File.exist?(req.file_name) || !File.readable?(req.file_name)
+ raise ArgumentError.new("Unable to open specified file.")
+ end
+ request_body = File.read(req.file_name)
+ elsif req.upload_data
+ request_body = req.upload_data
+ else
+ raise ArgumentError.new("Must provide either data or a filename when doing a PUT or POST")
end
- request_body = File.read(req.file_name)
- elsif req.upload_data
- request_body = req.upload_data
- else
- raise ArgumentError.new("Must provide either data or a filename when doing a PUT or POST")
end
- end
- request_signature = WebMock::RequestSignature.new(
- req.action,
- uri.to_s,
- :body => request_body,
- :headers => req.headers
- )
- request_signature
- end
+ request_signature = WebMock::RequestSignature.new(
+ req.action,
+ uri.to_s,
+ :body => request_body,
+ :headers => req.headers
+ )
+ request_signature
+ end
- def build_patron_response(webmock_response)
- raise Patron::TimeoutError if webmock_response.should_timeout
- webmock_response.raise_error_if_any
- res = Patron::Response.new
- res.instance_variable_set(:@body, webmock_response.body)
- res.instance_variable_set(:@status, webmock_response.status[0])
- res.instance_variable_set(:@status_line, webmock_response.status[1])
- res.instance_variable_set(:@headers, webmock_response.headers)
- res
- end
+ def self.build_patron_response(webmock_response)
+ raise ::Patron::TimeoutError if webmock_response.should_timeout
+ webmock_response.raise_error_if_any
+ res = ::Patron::Response.new
+ res.instance_variable_set(:@body, webmock_response.body)
+ res.instance_variable_set(:@status, webmock_response.status[0])
+ res.instance_variable_set(:@status_line, webmock_response.status[1])
+ res.instance_variable_set(:@headers, webmock_response.headers)
+ res
+ end
- def build_webmock_response(patron_response)
- webmock_response = WebMock::Response.new
- reason = patron_response.status_line.
- scan(%r(\AHTTP/(\d+\.\d+)\s+(\d\d\d)\s*([^\r\n]+)?))[0][2]
- webmock_response.status = [patron_response.status, reason]
- webmock_response.body = patron_response.body
- webmock_response.headers = patron_response.headers
- webmock_response
+ def self.build_webmock_response(patron_response)
+ webmock_response = WebMock::Response.new
+ reason = patron_response.status_line.
+ scan(%r(\AHTTP/(\d+\.\d+)\s+(\d\d\d)\s*([^\r\n]+)?))[0][2]
+ webmock_response.status = [patron_response.status, reason]
+ webmock_response.body = patron_response.body
+ webmock_response.headers = patron_response.headers
+ webmock_response
+ end
end
-
end
end
-
end
View
@@ -26,15 +26,11 @@ def self.version
end
def self.disable!
- Config.instance.disabled = true
+ HttpLibAdapterRegistry.instance.each_adapter(&:disable!)
end
def self.enable!
- Config.instance.disabled = false
- end
-
- def self.disabled?
- !!Config.instance.disabled
+ HttpLibAdapterRegistry.instance.each_adapter(&:enable!)
end
def self.allow_net_connect!(options = {})
@@ -101,4 +97,5 @@ def #{method}(*args, &block)
))
end
+ self.enable!
end

0 comments on commit b3d6045

Please sign in to comment.