diff --git a/README.rdoc b/README.rdoc index fb245133..e8896296 100644 --- a/README.rdoc +++ b/README.rdoc @@ -44,12 +44,12 @@ the API on a whim. == Testing -* Typhoeus and Yajl are needed for tests :( +* Yajl are needed for tests :( * Live Sinatra server is required for tests: `ruby test/live_server.rb` to start it. == TODO -* gracefully skip tests for Typhoeus, Yajl, and other optional libraries if they don't exist. +* gracefully skip tests for Yajl and other optional libraries if they don't exist. * gracefully skip live http server tests if the sinatra server is not running. * lots of other crap diff --git a/lib/faraday.rb b/lib/faraday.rb index a53a7807..b2ccaba3 100644 --- a/lib/faraday.rb +++ b/lib/faraday.rb @@ -13,6 +13,14 @@ module Faraday module Adapter autoload :NetHttp, 'faraday/adapter/net_http' autoload :Typhoeus, 'faraday/adapter/typhoeus' + + def self.adapters + constants + end + + def self.loaded_adapters + adapters.map { |c| const_get(c) }.select { |a| a.loaded } + end end end diff --git a/lib/faraday/adapter/net_http.rb b/lib/faraday/adapter/net_http.rb index 42e62915..71554bcc 100644 --- a/lib/faraday/adapter/net_http.rb +++ b/lib/faraday/adapter/net_http.rb @@ -2,6 +2,8 @@ require 'net/http' module Faraday module Adapter module NetHttp + def self.loaded() true end + def _get(uri, request_headers) http = Net::HTTP.new(uri.host, uri.port) response_class.new do |resp| diff --git a/lib/faraday/adapter/typhoeus.rb b/lib/faraday/adapter/typhoeus.rb index e0616e42..877cd9b0 100644 --- a/lib/faraday/adapter/typhoeus.rb +++ b/lib/faraday/adapter/typhoeus.rb @@ -1,46 +1,56 @@ -require 'typhoeus' + module Faraday module Adapter module Typhoeus - def in_parallel? - !!@parallel_manager + class << self + attr_accessor :loaded end - def in_parallel(options = {}) - setup_parallel_manager(options) - yield - run_parallel_requests - end + begin + require 'typhoeus' + self.loaded = true - def setup_parallel_manager(options = {}) - @parallel_manager ||= ::Typhoeus::Hydra.new(options) - end - - def run_parallel_requests - @parallel_manager.run - @parallel_manager = nil - end - - def _get(uri, request_headers) - response_class.new do |resp| - is_async = in_parallel? - setup_parallel_manager - req = ::Typhoeus::Request.new(uri.to_s, :headers => request_headers, :method => :get) - req.on_complete do |response| - resp.process!(response.body) - resp.headers = parse_response_headers(response.headers) - end - @parallel_manager.queue(req) - if !is_async then run_parallel_requests end + def in_parallel? + !!@parallel_manager end - end - - def parse_response_headers(header_string) - Hash[*header_string.split(/\r\n/). - tap { |a| a.shift }. # drop the HTTP status line - map! { |h| h.split(/:\s+/,2) }. # split key and value - map! { |(k, v)| [k.downcase, v] }. - tap { |a| a.flatten! }] + + def in_parallel(options = {}) + setup_parallel_manager(options) + yield + run_parallel_requests + end + + def setup_parallel_manager(options = {}) + @parallel_manager ||= ::Typhoeus::Hydra.new(options) + end + + def run_parallel_requests + @parallel_manager.run + @parallel_manager = nil + end + + def _get(uri, request_headers) + response_class.new do |resp| + is_async = in_parallel? + setup_parallel_manager + req = ::Typhoeus::Request.new(uri.to_s, :headers => request_headers, :method => :get) + req.on_complete do |response| + resp.process!(response.body) + resp.headers = parse_response_headers(response.headers) + end + @parallel_manager.queue(req) + if !is_async then run_parallel_requests end + end + end + + def parse_response_headers(header_string) + Hash[*header_string.split(/\r\n/). + tap { |a| a.shift }. # drop the HTTP status line + map! { |h| h.split(/:\s+/,2) }. # split key and value + map! { |(k, v)| [k.downcase, v] }. + tap { |a| a.flatten! }] + end + rescue LoadError end end end diff --git a/test/adapter/typhoeus_test.rb b/test/adapter/typhoeus_test.rb index 40fc1b72..b1b4fda2 100644 --- a/test/adapter/typhoeus_test.rb +++ b/test/adapter/typhoeus_test.rb @@ -1,24 +1,26 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper')) -class TyphoeusTest < Faraday::TestCase - describe "#parse_response_headers" do - before do - @conn = Object.new.extend(Faraday::Adapter::Typhoeus) - end +if Faraday::Adapter::Typhoeus.loaded + class TyphoeusTest < Faraday::TestCase + describe "#parse_response_headers" do + before do + @conn = Object.new.extend(Faraday::Adapter::Typhoeus) + end - it "leaves http status line out" do - headers = @conn.parse_response_headers("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n") - assert_equal %w(content-type), headers.keys - end + it "leaves http status line out" do + headers = @conn.parse_response_headers("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n") + assert_equal %w(content-type), headers.keys + end - it "parses lower-cased header name and value" do - headers = @conn.parse_response_headers("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n") - assert_equal 'text/html', headers['content-type'] - end + it "parses lower-cased header name and value" do + headers = @conn.parse_response_headers("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n") + assert_equal 'text/html', headers['content-type'] + end - it "parses lower-cased header name and value with colon" do - headers = @conn.parse_response_headers("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nLocation: http://sushi.com/\r\n\r\n") - assert_equal 'http://sushi.com/', headers['location'] + it "parses lower-cased header name and value with colon" do + headers = @conn.parse_response_headers("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nLocation: http://sushi.com/\r\n\r\n") + assert_equal 'http://sushi.com/', headers['location'] + end end end -end +end \ No newline at end of file diff --git a/test/adapter_test.rb b/test/adapter_test.rb index 4d4a9216..1cb401dd 100644 --- a/test/adapter_test.rb +++ b/test/adapter_test.rb @@ -5,7 +5,7 @@ class AdapterTest < Faraday::TestCase @connection = Faraday::Connection.new(LIVE_SERVER) end - [Faraday::Adapter::NetHttp, Faraday::Adapter::Typhoeus].each do |adapter| + Faraday::Adapter.loaded_adapters.each do |adapter| describe "#get with #{adapter} adapter" do before do @connection.extend adapter @@ -26,32 +26,34 @@ class AdapterTest < Faraday::TestCase end end - describe "async Typhoeus requests" do - before do - @connection.extend Faraday::Adapter::Typhoeus - end - - it "clears parallel manager after running a single request" do - assert !@connection.in_parallel? - resp = @connection.get('hello_world') - assert !@connection.in_parallel? - assert_equal 'hello world', @connection.get('hello_world').body - end - - it "uses parallel manager to run multiple json requests" do - resp1, resp2 = nil, nil - - @connection.response_class = Faraday::Response::YajlResponse - @connection.in_parallel do - resp1 = @connection.get('json') - resp2 = @connection.get('json') - assert @connection.in_parallel? - assert_nil resp1.body - assert_nil resp2.body + if Faraday::Adapter::Typhoeus.loaded + describe "async Typhoeus requests" do + before do + @connection.extend Faraday::Adapter::Typhoeus + end + + it "clears parallel manager after running a single request" do + assert !@connection.in_parallel? + resp = @connection.get('hello_world') + assert !@connection.in_parallel? + assert_equal 'hello world', @connection.get('hello_world').body + end + + it "uses parallel manager to run multiple json requests" do + resp1, resp2 = nil, nil + + @connection.response_class = Faraday::Response::YajlResponse + @connection.in_parallel do + resp1 = @connection.get('json') + resp2 = @connection.get('json') + assert @connection.in_parallel? + assert_nil resp1.body + assert_nil resp2.body + end + assert !@connection.in_parallel? + assert_equal [1,2,3], resp1.body + assert_equal [1,2,3], resp2.body end - assert !@connection.in_parallel? - assert_equal [1,2,3], resp1.body - assert_equal [1,2,3], resp2.body end end end diff --git a/test/helper.rb b/test/helper.rb index 66cf7690..454a38fb 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -1,5 +1,8 @@ require 'rubygems' require 'context' +if ENV['LEFTRIGHT'] + require 'leftright' +end $LOAD_PATH.unshift(File.dirname(__FILE__)) $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))