Merge branch 'master' of https://github.com/josevalim/faraday into josevalim-master

This commit is contained in:
rick 2010-10-05 10:42:25 -07:00
commit 4f7ba6624d
6 changed files with 103 additions and 62 deletions

View File

@ -9,7 +9,7 @@ Gem::Specification.new do |s|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["rick"]
s.date = %q{2010-05-28}
s.date = %q{2010-10-02}
s.description = %q{HTTP/REST API client library with pluggable components}
s.email = %q{technoweenie@gmail.com}
s.extra_rdoc_files = [
@ -25,6 +25,7 @@ Gem::Specification.new do |s|
"VERSION",
"faraday.gemspec",
"lib/faraday.rb",
"lib/faraday/adapter/action_dispatch.rb",
"lib/faraday/adapter/net_http.rb",
"lib/faraday/adapter/patron.rb",
"lib/faraday/adapter/test.rb",
@ -39,6 +40,7 @@ Gem::Specification.new do |s|
"lib/faraday/response.rb",
"lib/faraday/response/active_support_json.rb",
"lib/faraday/response/yajl.rb",
"lib/faraday/utils.rb",
"test/adapters/live_test.rb",
"test/adapters/test_middleware_test.rb",
"test/adapters/typhoeus_test.rb",
@ -53,7 +55,7 @@ Gem::Specification.new do |s|
s.homepage = %q{http://github.com/technoweenie/faraday}
s.rdoc_options = ["--charset=UTF-8"]
s.require_paths = ["lib"]
s.rubygems_version = %q{1.3.6}
s.rubygems_version = %q{1.3.7}
s.summary = %q{HTTP/REST API client library}
s.test_files = [
"test/adapters/live_test.rb",
@ -72,7 +74,7 @@ Gem::Specification.new do |s|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
s.specification_version = 3
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q<rack>, [">= 1.0.1"])
s.add_runtime_dependency(%q<addressable>, [">= 2.1.1"])
else

View File

@ -54,7 +54,8 @@ module Faraday
:Builder => 'builder',
:Request => 'request',
:Response => 'response',
:Error => 'error'
:Error => 'error',
:Utils => 'utils'
module Adapter
extend AutoloadHelper

View File

@ -19,7 +19,7 @@ module Faraday
class Stubs
def initialize
# {:get => [Stub, Stub]}
@stack = {}
@stack, @consumed = {}, {}
yield self if block_given?
end
@ -29,8 +29,15 @@ module Faraday
def match(request_method, path, body)
return false if !@stack.key?(request_method)
stub = @stack[request_method].detect { |stub| stub.matches?(path, body) }
@stack[request_method].delete stub
stack = @stack[request_method]
consumed = (@consumed[request_method] ||= [])
if stub = matches?(stack, path, body)
consumed << stack.delete(stub)
stub
else
matches?(consumed, path, body)
end
end
def get(path, &block)
@ -53,10 +60,6 @@ module Faraday
new_stub(:delete, path, &block)
end
def new_stub(request_method, path, body=nil, &block)
(@stack[request_method] ||= []) << Stub.new(path, body, block)
end
# Raises an error if any of the stubbed calls have not been made.
def verify_stubbed_calls
failed_stubs = []
@ -69,6 +72,16 @@ module Faraday
end
raise failed_stubs.join(" ") unless failed_stubs.size == 0
end
protected
def new_stub(request_method, path, body=nil, &block)
(@stack[request_method] ||= []) << Stub.new(path, body, block)
end
def matches?(stack, path, body)
stack.detect { |stub| stub.matches?(path, body) }
end
end
class Stub < Struct.new(:path, :body, :block)
@ -91,17 +104,8 @@ module Faraday
yield stubs
end
def request_uri(url)
(url.path != "" ? url.path : "/") +
(url.query ? "?#{sort_query_params(url.query)}" : "")
end
def sort_query_params(query)
query.split('&').sort.join('&')
end
def call(env)
if stub = stubs.match(env[:method], request_uri(env[:url]), env[:body])
if stub = stubs.match(env[:method], Faraday::Utils.normalize_path(env[:url]), env[:body])
status, headers, body = stub.block.call(env)
env.update \
:status => status,

View File

@ -4,20 +4,7 @@ require 'base64'
module Faraday
class Connection
include Addressable, Rack::Utils
HEADERS = Hash.new do |h, k|
if k.respond_to?(:to_str)
k
else
k.to_s.split('_'). # :user_agent => %w(user agent)
each { |w| w.capitalize! }. # => %w(User Agent)
join('-') # => "User-Agent"
end
end
HEADERS.update \
:etag => "ETag"
HEADERS.values.each { |v| v.freeze }
include Addressable, Faraday::Utils
METHODS = Set.new [:get, :post, :put, :delete, :head]
METHODS_WITH_BODIES = Set.new [:post, :put]
@ -226,33 +213,6 @@ module Faraday
uri
end
# turns param keys into strings
def merge_params(existing_params, new_params)
new_params.each do |key, value|
existing_params[key.to_s] = value
end
end
# turns headers keys and values into strings. Look up symbol keys in the
# the HEADERS hash.
#
# h = merge_headers(HeaderHash.new, :content_type => 'text/plain')
# h['Content-Type'] # = 'text/plain'
#
def merge_headers(existing_headers, new_headers)
new_headers.each do |key, value|
existing_headers[HEADERS[key]] = value.to_s
end
end
# Be sure to URI escape '+' symbols to %2B. Otherwise, they get interpreted
# as spaces.
def escape(s)
s.to_s.gsub(/([^a-zA-Z0-9_.-]+)/n) do
'%' << $1.unpack('H2'*bytesize($1)).join('%').tap { |c| c.upcase! }
end
end
def proxy_arg_to_uri(arg)
case arg
when String then URI.parse(arg)

63
lib/faraday/utils.rb Normal file
View File

@ -0,0 +1,63 @@
module Faraday
module Utils
include Rack::Utils
extend Rack::Utils
extend self
HEADERS = Hash.new do |h, k|
if k.respond_to?(:to_str)
k
else
k.to_s.split('_'). # :user_agent => %w(user agent)
each { |w| w.capitalize! }. # => %w(User Agent)
join('-') # => "User-Agent"
end
end
HEADERS.merge! :etag => "ETag"
HEADERS.values.each { |v| v.freeze }
# Make Rack::Utils build_query method public.
public :build_query
# Be sure to URI escape '+' symbols to %2B. Otherwise, they get interpreted
# as spaces.
def escape(s)
s.to_s.gsub(/([^a-zA-Z0-9_.-]+)/n) do
'%' << $1.unpack('H2'*bytesize($1)).join('%').tap { |c| c.upcase! }
end
end
# Turns param keys into strings
def merge_params(existing_params, new_params)
new_params.each do |key, value|
existing_params[key.to_s] = value
end
end
# Turns headers keys and values into strings. Look up symbol keys in the
# the HEADERS hash.
#
# h = merge_headers(HeaderHash.new, :content_type => 'text/plain')
# h['Content-Type'] # = 'text/plain'
#
def merge_headers(existing_headers, new_headers)
new_headers.each do |key, value|
existing_headers[HEADERS[key]] = value.to_s
end
end
# Receives a URL and returns just the path with the query string sorted.
def normalize_path(url)
(url.path != "" ? url.path : "/") +
(url.query ? "?#{sort_query_params(url.query)}" : "")
end
protected
def sort_query_params(query)
query.split('&').sort.join('&')
end
end
end

View File

@ -22,5 +22,16 @@ module Adapters
def test_middleware_with_simple_path_sets_body
assert_equal 'hello', @resp.body
end
def test_middleware_can_be_called_several_times
assert_equal 'hello', @conn.get("/hello").body
end
def test_middleware_allow_different_outcomes_for_the_same_request
@stubs.get('/hello') { [200, {'Content-Type' => 'text/html'}, 'hello'] }
@stubs.get('/hello') { [200, {'Content-Type' => 'text/html'}, 'world'] }
assert_equal 'hello', @conn.get("/hello").body
assert_equal 'world', @conn.get("/hello").body
end
end
end