faraday 0.7.5 → 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -9,8 +9,11 @@ group :test do
9
9
  gem 'em-synchrony', '~> 1.0', :require => ['em-synchrony', 'em-synchrony/em-http'], :platforms => :ruby_19
10
10
  gem 'excon', '~> 0.6'
11
11
  gem 'leftright', '~> 0.9', :require => false
12
+ end
13
+
14
+ platforms :ruby do
12
15
  gem 'patron', '~> 0.4'
13
- gem 'typhoeus', '~> 0.2'
16
+ gem 'typhoeus', '~> 0.3'
14
17
  # ActiveSupport::JSON will be used in ruby 1.8 and Yajl in 1.9; this is to test against both adapters
15
18
  gem 'activesupport', '~> 2.3', :require => nil, :platforms => [:ruby_18, :jruby]
16
19
  gem 'yajl-ruby', '~> 1.0', :require => 'yajl', :platforms => :ruby_19
data/Rakefile CHANGED
@@ -81,10 +81,6 @@ end
81
81
 
82
82
  desc "Create tag v#{version} and build and push #{gem_file} to Rubygems"
83
83
  task :release => :build do
84
- unless `git branch` =~ /^\* master$/
85
- puts "You must be on the master branch to release!"
86
- exit!
87
- end
88
84
  sh "git commit --allow-empty -a -m 'Release #{version}'"
89
85
  sh "git tag v#{version}"
90
86
  sh "git push origin master"
@@ -12,8 +12,8 @@ Gem::Specification.new do |s|
12
12
  ## If your rubyforge_project name is different, then edit it and comment out
13
13
  ## the sub! line in the Rakefile
14
14
  s.name = 'faraday'
15
- s.version = '0.7.5'
16
- s.date = '2011-10-04'
15
+ s.version = '0.7.6'
16
+ s.date = '2012-01-21'
17
17
  s.rubyforge_project = 'faraday'
18
18
 
19
19
  ## Make sure your summary is short. The description may be as long
@@ -32,12 +32,12 @@ Gem::Specification.new do |s|
32
32
  ## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
33
33
  s.require_paths = %w[lib]
34
34
 
35
- s.add_dependency 'addressable', '~> 2.2.6'
36
- s.add_dependency 'multipart-post', '~> 1.1.3'
37
- s.add_dependency 'rack', ['>= 1.1.0', '< 2']
38
- s.add_development_dependency 'rake', '~> 0.9'
39
- s.add_development_dependency 'test-unit', '~> 2.4'
40
- s.add_development_dependency 'webmock', '~> 1.7'
35
+ s.add_dependency 'addressable', '~> 2.2'
36
+ s.add_dependency 'multipart-post', '~> 1.1'
37
+ s.add_dependency 'rack', '~> 1.1'
38
+ s.add_development_dependency 'rake'
39
+ s.add_development_dependency 'test-unit'
40
+ s.add_development_dependency 'webmock'
41
41
 
42
42
  ## Leave this section as-is. It will be automatically generated from the
43
43
  ## contents of your Git repository via the gemspec task. DO NOT REMOVE
@@ -76,6 +76,7 @@ Gem::Specification.new do |s|
76
76
  test/adapters/logger_test.rb
77
77
  test/adapters/net_http_test.rb
78
78
  test/adapters/test_middleware_test.rb
79
+ test/adapters/typhoeus_test.rb
79
80
  test/connection_test.rb
80
81
  test/env_test.rb
81
82
  test/helper.rb
@@ -1,5 +1,5 @@
1
1
  module Faraday
2
- VERSION = "0.7.5"
2
+ VERSION = "0.7.6"
3
3
 
4
4
  class << self
5
5
  attr_accessor :default_adapter
@@ -17,8 +17,7 @@ module Faraday
17
17
 
18
18
  if http.use_ssl = (url.scheme == 'https' && (ssl = env[:ssl]) && true)
19
19
  http.verify_mode = ssl[:verify_mode] || begin
20
- if ssl.fetch(:verify, true)
21
- OpenSSL::SSL::VERIFY_PEER
20
+ if ssl.fetch(:verify, true)
22
21
  # Use the default cert store by default, i.e. system ca certs
23
22
  store = OpenSSL::X509::Store.new
24
23
  store.set_default_paths
@@ -40,11 +39,11 @@ module Faraday
40
39
  http.read_timeout = http.open_timeout = req[:timeout] if req[:timeout]
41
40
  http.open_timeout = req[:open_timeout] if req[:open_timeout]
42
41
 
43
- if :get != env[:method]
42
+ if :get != env[:method] or env[:body]
44
43
  http_request = Net::HTTPGenericRequest.new \
45
44
  env[:method].to_s.upcase, # request method
46
- !!env[:body], # is there data
47
- true, # does net/http love you, true or false?
45
+ !!env[:body], # is there request body
46
+ :head != env[:method], # is there response body
48
47
  url.request_uri, # request uri path
49
48
  env[:request_headers] # request headers
50
49
 
@@ -55,7 +54,7 @@ module Faraday
55
54
  end
56
55
 
57
56
  begin
58
- http_response = if :get == env[:method]
57
+ http_response = if :get == env[:method] and env[:body].nil?
59
58
  # prefer `get` to `request` because the former handles gzip (ruby 1.9)
60
59
  http.get url.request_uri, env[:request_headers]
61
60
  else
@@ -72,6 +71,8 @@ module Faraday
72
71
  end
73
72
 
74
73
  @app.call env
74
+ rescue Timeout::Error => err
75
+ raise Faraday::Error::TimeoutError, err
75
76
  end
76
77
 
77
78
  def net_http_class(env)
@@ -11,8 +11,13 @@ module Faraday
11
11
 
12
12
  session = ::Patron::Session.new
13
13
 
14
+ if req = env[:request]
15
+ session.timeout = session.connect_timeout = req[:timeout] if req[:timeout]
16
+ session.connect_timeout = req[:open_timeout] if req[:open_timeout]
17
+ end
18
+
14
19
  response = begin
15
- data = Connection::METHODS_WITH_BODIES.include?(env[:method]) ? env[:body].to_s : nil
20
+ data = env[:body] ? env[:body].to_s : nil
16
21
  session.request(env[:method], env[:url].to_s, env[:request_headers], :data => data)
17
22
  rescue Errno::ECONNREFUSED
18
23
  raise Error::ConnectionFailed, $!
@@ -21,6 +26,8 @@ module Faraday
21
26
  save_response(env, response.status, response.body, response.headers)
22
27
 
23
28
  @app.call env
29
+ rescue ::Patron::TimeoutError => err
30
+ raise Faraday::Error::TimeoutError, err
24
31
  end
25
32
 
26
33
  if loaded? && defined?(::Patron::Request::VALID_ACTIONS)
@@ -59,10 +59,18 @@ module Faraday
59
59
  new_stub(:put, path, body, &block)
60
60
  end
61
61
 
62
+ def patch(path, body=nil, &block)
63
+ new_stub(:patch, path, body, &block)
64
+ end
65
+
62
66
  def delete(path, &block)
63
67
  new_stub(:delete, path, &block)
64
68
  end
65
69
 
70
+ def options(path, &block)
71
+ new_stub(:options, path, &block)
72
+ end
73
+
66
74
  # Raises an error if any of the stubbed calls have not been made.
67
75
  def verify_stubbed_calls
68
76
  failed_stubs = []
@@ -29,16 +29,16 @@ module Faraday
29
29
  end
30
30
 
31
31
  env_req = env[:request]
32
-
32
+
33
33
  if proxy = env_req[:proxy]
34
34
  req.proxy = "#{proxy[:uri].host}:#{proxy[:uri].port}"
35
-
35
+
36
36
  if proxy[:username] && proxy[:password]
37
37
  req.proxy_username = proxy[:username]
38
38
  req.proxy_password = proxy[:password]
39
39
  end
40
40
  end
41
-
41
+
42
42
  req.timeout = req.connect_timeout = (env_req[:timeout] * 1000) if env_req[:timeout]
43
43
  req.connect_timeout = (env_req[:open_timeout] * 1000) if env_req[:open_timeout]
44
44
 
@@ -1,5 +1,6 @@
1
1
  require 'addressable/uri'
2
2
  require 'base64'
3
+ require 'cgi'
3
4
  require 'set'
4
5
  require 'faraday/builder'
5
6
  require 'faraday/request'
@@ -32,7 +33,10 @@ module Faraday
32
33
  @ssl = options[:ssl] || {}
33
34
  @parallel_manager = options[:parallel]
34
35
 
36
+ @path_prefix = @host = @port = @scheme = nil
35
37
  self.url_prefix = url if url
38
+
39
+ @proxy = nil
36
40
  proxy(options[:proxy])
37
41
 
38
42
  @params.update options[:params] if options[:params]
@@ -145,17 +149,14 @@ module Faraday
145
149
  def proxy(arg = nil)
146
150
  return @proxy if arg.nil?
147
151
 
148
- @proxy =
149
- case arg
150
- when String then {:uri => proxy_arg_to_uri(arg)}
151
- when URI then {:uri => arg}
152
- when Hash
153
- if arg[:uri] = proxy_arg_to_uri(arg[:uri])
154
- arg
155
- else
156
- raise ArgumentError, "no :uri option."
157
- end
158
- end
152
+ @proxy = if arg.is_a? Hash
153
+ uri = arg.fetch(:uri) { raise ArgumentError, "no :uri option" }
154
+ arg.merge :uri => URI.parse(uri)
155
+ else
156
+ {:uri => URI.parse(arg)}
157
+ end
158
+ rescue TypeError
159
+ raise ArgumentError, "bad uri"
159
160
  end
160
161
 
161
162
  # Parses the giving url with Addressable::URI and stores the individual
@@ -177,7 +178,9 @@ module Faraday
177
178
  self.path_prefix = uri.path
178
179
 
179
180
  @params.merge_query(uri.query)
180
- basic_auth(uri.user, uri.password) if uri.user && uri.password
181
+ if uri.user && uri.password
182
+ basic_auth(CGI.unescape(uri.user), CGI.unescape(uri.password))
183
+ end
181
184
 
182
185
  uri
183
186
  end
@@ -239,12 +242,5 @@ module Faraday
239
242
  def dup
240
243
  self.class.new(build_url(''), :headers => headers.dup, :params => params.dup, :builder => builder.dup, :ssl => ssl.dup)
241
244
  end
242
-
243
- def proxy_arg_to_uri(arg)
244
- case arg
245
- when String then URI.parse(arg)
246
- when URI then arg
247
- end
248
- end
249
245
  end
250
246
  end
@@ -3,9 +3,9 @@ module Faraday
3
3
  class ClientError < StandardError
4
4
  attr_reader :response
5
5
 
6
- def initialize(ex)
6
+ def initialize(ex, response = nil)
7
7
  @wrapped_exception = nil
8
- @response = nil
8
+ @response = response
9
9
 
10
10
  if ex.respond_to?(:backtrace)
11
11
  super(ex.message)
@@ -34,7 +34,7 @@ module Faraday
34
34
  class ConnectionFailed < ClientError; end
35
35
  class ResourceNotFound < ClientError; end
36
36
  class ParsingError < ClientError; end
37
-
37
+ class TimeoutError < ClientError; end
38
38
  class MissingDependency < StandardError; end
39
39
  end
40
40
  end
@@ -19,11 +19,11 @@ module Faraday
19
19
  end
20
20
 
21
21
  def self.loaded?
22
- @load_error.nil?
22
+ !defined? @load_error or @load_error.nil?
23
23
  end
24
24
 
25
25
  def initialize(app = nil)
26
26
  @app = app
27
27
  end
28
28
  end
29
- end
29
+ end
@@ -21,12 +21,11 @@ module Faraday
21
21
  )
22
22
  end
23
23
 
24
- def has_multipart?(body)
25
- body.values.each do |val|
26
- if val.respond_to?(:content_type)
27
- return true
28
- elsif val.respond_to?(:values)
29
- return true if has_multipart?(val)
24
+ def has_multipart?(obj)
25
+ # string is an enum in 1.8, returning list of itself
26
+ if obj.respond_to?(:each) && !obj.is_a?(String)
27
+ (obj.respond_to?(:values) ? obj.values : obj).each do |val|
28
+ return true if (val.respond_to?(:content_type) || has_multipart?(val))
30
29
  end
31
30
  end
32
31
  false
@@ -13,10 +13,8 @@ module Faraday
13
13
  end
14
14
  @app.call env
15
15
  end
16
-
16
+
17
17
  def match_content_type(env)
18
- type = request_type(env)
19
-
20
18
  if process_request?(env)
21
19
  env[:request_headers][CONTENT_TYPE] ||= self.class.mime_type
22
20
  yield env[:body] unless env[:body].respond_to?(:to_str)
@@ -5,8 +5,8 @@ module Faraday
5
5
  # Used for simple response middleware.
6
6
  class Middleware < Faraday::Middleware
7
7
  def call(env)
8
- @app.call(env).on_complete do |env|
9
- on_complete(env)
8
+ @app.call(env).on_complete do |environment|
9
+ on_complete(environment)
10
10
  end
11
11
  end
12
12
 
@@ -8,7 +8,7 @@ module Faraday
8
8
  raise Faraday::Error::ClientError, response_values(env)
9
9
  end
10
10
  end
11
-
11
+
12
12
  def response_values(env)
13
13
  {:status => env[:status], :headers => env[:response_headers], :body => env[:body]}
14
14
  end
@@ -10,7 +10,7 @@ end
10
10
  module Faraday
11
11
  class CompositeReadIO < ::CompositeReadIO
12
12
  attr_reader :length
13
-
13
+
14
14
  def initialize(parts)
15
15
  @length = parts.inject(0) { |sum, part| sum + part.length }
16
16
  ios = parts.map{ |part| part.to_io }
@@ -35,7 +35,7 @@ module Faraday
35
35
  return unless header_string && !header_string.empty?
36
36
  header_string.split(/\r\n/).
37
37
  tap { |a| a.shift if a.first.index('HTTP/') == 0 }. # drop the HTTP status line
38
- map { |h| h.split(/:\s+/, 2) }.reject { |(k, v)| k.nil? }. # split key and value, ignore blank lines
38
+ map { |h| h.split(/:\s+/, 2) }.reject { |p| p[0].nil? }. # split key and value, ignore blank lines
39
39
  each { |key, value|
40
40
  # join multiple values with a comma
41
41
  if self[key] then self[key] << ', ' << value
@@ -109,10 +109,10 @@ module Faraday
109
109
  def build_nested_query(value, prefix = nil)
110
110
  case value
111
111
  when Array
112
- value.map { |v| build_nested_query(v, "#{prefix}[]") }.join("&")
112
+ value.map { |v| build_nested_query(v, "#{prefix}%5B%5D") }.join("&")
113
113
  when Hash
114
114
  value.map { |k, v|
115
- build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
115
+ build_nested_query(v, prefix ? "#{prefix}%5B#{escape(k)}%5D" : escape(k))
116
116
  }.join("&")
117
117
  when NilClass
118
118
  prefix
@@ -125,8 +125,10 @@ module Faraday
125
125
  # Be sure to URI escape '+' symbols to %2B. Otherwise, they get interpreted
126
126
  # as spaces.
127
127
  def escape(s)
128
- s.to_s.gsub(/([^a-zA-Z0-9_.-]+)/n) do
129
- '%' << $1.unpack('H2'*bytesize($1)).join('%').tap { |c| c.upcase! }
128
+ s = s.to_s
129
+ s = s.dup.force_encoding('binary') if s.respond_to? :force_encoding
130
+ s.gsub(/([^a-zA-Z0-9_.-]+)/n) do |match|
131
+ '%' << match.unpack('H2'*bytesize(match)).join('%').tap { |c| c.upcase! }
130
132
  end
131
133
  end
132
134
 
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper'))
1
+ require File.expand_path("../../helper", __FILE__)
2
2
 
3
3
  if !Faraday::TestCase::LIVE_SERVER
4
4
  warn "warning: test server not specified; skipping live server tests"
@@ -10,6 +10,8 @@ else
10
10
  else
11
11
  loaded_adapters = Faraday::Adapter.all_loaded_constants
12
12
  loaded_adapters -= [Faraday::Adapter::ActionDispatch]
13
+ # https://github.com/geemus/excon/issues/98
14
+ loaded_adapters -= [Faraday::Adapter::Excon] if defined? RUBY_ENGINE and "rbx" == RUBY_ENGINE
13
15
  loaded_adapters << :default
14
16
  end
15
17
 
@@ -27,8 +29,8 @@ else
27
29
 
28
30
  define_method "test_#{adapter}_GET_retrieves_the_response_headers" do
29
31
  response = create_connection(adapter).get('hello_world')
30
- assert_match /text\/html/, response.headers['Content-Type'], 'original case fail'
31
- assert_match /text\/html/, response.headers['content-type'], 'lowercase fail'
32
+ assert_match(/text\/html/, response.headers['Content-Type'], 'original case fail')
33
+ assert_match(/text\/html/, response.headers['content-type'], 'lowercase fail')
32
34
  end
33
35
 
34
36
  # https://github.com/geemus/excon/issues/10
@@ -39,6 +41,17 @@ else
39
41
  end
40
42
  end
41
43
 
44
+ # https://github.com/dbalatero/typhoeus/issues/75
45
+ # https://github.com/toland/patron/issues/52
46
+ unless %[Faraday::Adapter::Typhoeus Faraday::Adapter::Patron].include? adapter.to_s
47
+ define_method "test_#{adapter}_GET_with_body" do
48
+ response = create_connection(adapter).get('echo') do |req|
49
+ req.body = {'bodyrock' => true}
50
+ end
51
+ assert_equal %(get {"bodyrock"=>"true"}), response.body
52
+ end
53
+ end
54
+
42
55
  define_method "test_#{adapter}_POST_send_url_encoded_params" do
43
56
  resp = create_connection(adapter).post do |req|
44
57
  req.url 'echo_name'
@@ -56,7 +69,7 @@ else
56
69
  end
57
70
 
58
71
  define_method "test_#{adapter}_POST_retrieves_the_response_headers" do
59
- assert_match /text\/html/, create_connection(adapter).post('echo_name').headers['content-type']
72
+ assert_match(/text\/html/, create_connection(adapter).post('echo_name').headers['content-type'])
60
73
  end
61
74
 
62
75
  define_method "test_#{adapter}_POST_sends_files" do
@@ -90,7 +103,7 @@ else
90
103
  # https://github.com/dbalatero/typhoeus/issues/84
91
104
  if ENV['FORCE'] || !%w[Faraday::Adapter::Patron Faraday::Adapter::Typhoeus].include?(adapter.to_s)
92
105
  define_method "test_#{adapter}_PUT_retrieves_the_response_headers" do
93
- assert_match /text\/html/, create_connection(adapter).put('echo_name').headers['content-type']
106
+ assert_match(/text\/html/, create_connection(adapter).put('echo_name').headers['content-type'])
94
107
  end
95
108
  end
96
109
 
@@ -113,7 +126,7 @@ else
113
126
  resp = create_connection(adapter).head do |req|
114
127
  req.url 'hello', 'name' => 'zack'
115
128
  end
116
- assert_match /text\/html/, resp.headers['content-type']
129
+ assert_match(/text\/html/, resp.headers['content-type'])
117
130
  end
118
131
 
119
132
  define_method "test_#{adapter}_HEAD_retrieves_no_response_body" do
@@ -121,21 +134,21 @@ else
121
134
  end
122
135
 
123
136
  define_method "test_#{adapter}_HEAD_retrieves_the_response_headers" do
124
- assert_match /text\/html/, create_connection(adapter).head('hello_world').headers['content-type']
137
+ assert_match(/text\/html/, create_connection(adapter).head('hello_world').headers['content-type'])
125
138
  end
126
139
 
127
140
  define_method "test_#{adapter}_DELETE_retrieves_the_response_headers" do
128
- assert_match /text\/html/, create_connection(adapter).delete('delete_with_json').headers['content-type']
141
+ assert_match(/text\/html/, create_connection(adapter).delete('delete_with_json').headers['content-type'])
129
142
  end
130
143
 
131
144
  define_method "test_#{adapter}_DELETE_retrieves_the_body" do
132
- assert_match /deleted/, create_connection(adapter).delete('delete_with_json').body
145
+ assert_match(/deleted/, create_connection(adapter).delete('delete_with_json').body)
133
146
  end
134
147
 
135
148
  define_method "test_#{adapter}_async_requests_clear_parallel_manager_after_running_a_single_request" do
136
149
  connection = create_connection(adapter)
137
150
  assert !connection.in_parallel?
138
- resp = connection.get('hello_world')
151
+ connection.get('hello_world')
139
152
  assert !connection.in_parallel?
140
153
  assert_equal 'hello world', connection.get('hello_world').body
141
154
  end
@@ -173,9 +186,18 @@ else
173
186
  end
174
187
  end
175
188
  end
189
+
190
+ if %w[Faraday::Adapter::Patron Faraday::Adapter::NetHttp].include?(adapter.to_s)
191
+ define_method "test_#{adapter}_timeout" do
192
+ conn = create_connection(adapter, :request => {:timeout => 1, :read_timeout => 1})
193
+ assert_raise Faraday::Error::TimeoutError do
194
+ conn.get '/slow'
195
+ end
196
+ end
197
+ end
176
198
  end
177
199
 
178
- def create_connection(adapter)
200
+ def create_connection(adapter, options = {})
179
201
  if adapter == :default
180
202
  builder_block = nil
181
203
  else
@@ -185,8 +207,8 @@ else
185
207
  b.use adapter
186
208
  end
187
209
  end
188
-
189
- Faraday::Connection.new(LIVE_SERVER, &builder_block).tap do |conn|
210
+
211
+ Faraday::Connection.new(LIVE_SERVER, options, &builder_block).tap do |conn|
190
212
  conn.headers['X-Faraday-Adapter'] = adapter.to_s
191
213
  adapter_handler = conn.builder.handlers.last
192
214
  conn.builder.insert_before adapter_handler, Faraday::Response::RaiseError
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper'))
2
+
3
+ module Adapters
4
+ class TyphoeusTest < Faraday::TestCase
5
+ def setup
6
+ @connection = Faraday.new('http://disney.com') do |b|
7
+ b.adapter :typhoeus
8
+ end
9
+ end
10
+
11
+ def test_handles_user_agent
12
+ # default typhoeus agent
13
+ stub_request(:get, 'disney.com/world').with(:headers => {'User-Agent'=>'Faraday Agent'}){ |request|
14
+ request.headers["User-Agent"] == 'Faraday Agent'
15
+ }
16
+ @connection.get('/world', :user_agent => 'Faraday Agent')
17
+ end
18
+
19
+ end if defined? ::Typhoeus
20
+ end
@@ -1,4 +1,5 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
+ require 'uri'
2
3
 
3
4
  class TestConnection < Faraday::TestCase
4
5
  def test_initialize_parses_host_out_of_given_url
@@ -73,6 +74,11 @@ class TestConnection < Faraday::TestCase
73
74
  assert_equal 'Basic YWxhZGRpbjpvcGVuc2VzYW1l', conn.headers['Authorization']
74
75
  end
75
76
 
77
+ def test_auto_parses_basic_auth_from_url_and_unescapes
78
+ conn = Faraday::Connection.new :url => "http://foo%40bar.com:pass%20word@sushi.com/fish"
79
+ assert_equal 'Basic Zm9vQGJhci5jb206cGFzcyB3b3Jk', conn.headers['Authorization']
80
+ end
81
+
76
82
  def test_token_auth_sets_authorization_header
77
83
  conn = Faraday::Connection.new
78
84
  conn.token_auth 'abcdef'
@@ -147,13 +153,20 @@ class TestConnection < Faraday::TestCase
147
153
  assert_equal '/sake.html', uri.path
148
154
  end
149
155
 
150
- def test_build_url_doesnt_add_ending_slash
156
+ def test_build_url_doesnt_add_ending_slash_given_nil_url
151
157
  conn = Faraday::Connection.new
152
158
  conn.url_prefix = "http://sushi.com/nigiri"
153
159
  uri = conn.build_url(nil)
154
160
  assert_equal "/nigiri", uri.path
155
161
  end
156
162
 
163
+ def test_build_url_doesnt_add_ending_slash_given_empty_url
164
+ conn = Faraday::Connection.new
165
+ conn.url_prefix = "http://sushi.com/nigiri"
166
+ uri = conn.build_url('')
167
+ assert_equal "/nigiri", uri.path
168
+ end
169
+
157
170
  def test_build_url_parses_url_params_into_query
158
171
  conn = Faraday::Connection.new
159
172
  uri = conn.build_url("http://sushi.com/sake.html", 'a[b]' => '1 + 2')
@@ -196,6 +209,12 @@ class TestConnection < Faraday::TestCase
196
209
  assert_equal 'https://sushi.com/sushi/sake.html', uri.to_s
197
210
  end
198
211
 
212
+ def test_build_url_handles_uri_instances
213
+ conn = Faraday::Connection.new
214
+ uri = conn.build_url(URI('/sake.html'))
215
+ assert_equal '/sake.html', uri.path
216
+ end
217
+
199
218
  def test_proxy_accepts_string
200
219
  conn = Faraday::Connection.new
201
220
  conn.proxy 'http://proxy.com'
@@ -203,13 +222,20 @@ class TestConnection < Faraday::TestCase
203
222
  assert_equal [:uri], conn.proxy.keys
204
223
  end
205
224
 
206
- def test_proxy_accepts_uri
225
+ def test_proxy_accepts_addressable_uri
207
226
  conn = Faraday::Connection.new
208
227
  conn.proxy Addressable::URI.parse('http://proxy.com')
209
228
  assert_equal 'proxy.com', conn.proxy[:uri].host
210
229
  assert_equal [:uri], conn.proxy.keys
211
230
  end
212
231
 
232
+ def test_proxy_accepts_stdlib_uri
233
+ conn = Faraday::Connection.new
234
+ conn.proxy URI('http://proxy.com')
235
+ assert_equal 'proxy.com', conn.proxy[:uri].host
236
+ assert_equal [:uri], conn.proxy.keys
237
+ end
238
+
213
239
  def test_proxy_accepts_hash_with_string_uri
214
240
  conn = Faraday::Connection.new
215
241
  conn.proxy :uri => 'http://proxy.com', :user => 'rick'
@@ -112,45 +112,45 @@ class ResponseTest < Faraday::TestCase
112
112
  }
113
113
  @response = Faraday::Response.new @env
114
114
  end
115
-
115
+
116
116
  def test_finished
117
117
  assert @response.finished?
118
118
  end
119
-
119
+
120
120
  def test_error_on_finish
121
121
  assert_raises RuntimeError do
122
122
  @response.finish({})
123
123
  end
124
124
  end
125
-
125
+
126
126
  def test_not_success
127
127
  assert !@response.success?
128
128
  end
129
-
129
+
130
130
  def test_status
131
131
  assert_equal 404, @response.status
132
132
  end
133
-
133
+
134
134
  def test_body
135
135
  assert_equal 'yikes', @response.body
136
136
  end
137
-
137
+
138
138
  def test_headers
139
139
  assert_equal 'text/plain', @response.headers['Content-Type']
140
140
  assert_equal 'text/plain', @response['content-type']
141
141
  end
142
-
142
+
143
143
  def test_apply_request
144
144
  @response.apply_request :body => 'a=b', :method => :post
145
145
  assert_equal 'yikes', @response.body
146
146
  assert_equal :post, @response.env[:method]
147
147
  end
148
-
148
+
149
149
  def test_marshal
150
150
  @response = Faraday::Response.new
151
151
  @response.on_complete { }
152
152
  @response.finish @env.merge(:custom => 'moo')
153
-
153
+
154
154
  loaded = Marshal.load Marshal.dump(@response)
155
155
  assert_nil loaded.env[:custom]
156
156
  assert_equal %w[body response_headers status], loaded.env.keys.map { |k| k.to_s }.sort
@@ -1,5 +1,5 @@
1
- require 'rubygems'
2
1
  require 'test/unit'
2
+ require 'stringio'
3
3
 
4
4
  if ENV['LEFTRIGHT']
5
5
  begin
@@ -9,10 +9,6 @@ if ENV['LEFTRIGHT']
9
9
  end
10
10
  end
11
11
 
12
- unless $LOAD_PATH.include? 'lib'
13
- $LOAD_PATH.unshift(File.dirname(__FILE__))
14
- $LOAD_PATH.unshift(File.join($LOAD_PATH.first, '..', 'lib'))
15
- end
16
12
  require 'faraday'
17
13
 
18
14
  begin
@@ -28,12 +24,22 @@ module Faraday
28
24
  LIVE_SERVER = case ENV['LIVE']
29
25
  when /^http/ then ENV['LIVE']
30
26
  when nil then nil
31
- else 'http://localhost:4567'
27
+ else 'http://127.0.0.1:4567'
32
28
  end
33
29
 
34
30
  def test_default
35
31
  assert true
36
32
  end unless defined? ::MiniTest
33
+
34
+ def capture_warnings
35
+ old, $stderr = $stderr, StringIO.new
36
+ begin
37
+ yield
38
+ $stderr.string
39
+ ensure
40
+ $stderr = old
41
+ end
42
+ end
37
43
  end
38
44
  end
39
45
 
@@ -1,6 +1,18 @@
1
1
  require 'sinatra'
2
2
  set :logging, false
3
3
 
4
+ [:get, :post, :put, :patch, :delete, :options].each do |method|
5
+ send(method, '/echo') do
6
+ kind = request.request_method.downcase
7
+ out = kind.dup
8
+ out << ' ?' << request.GET.inspect if request.GET.any?
9
+ out << ' ' << request.POST.inspect if request.POST.any?
10
+
11
+ content_type 'text/plain'
12
+ return out
13
+ end
14
+ end
15
+
4
16
  get '/hello_world' do
5
17
  'hello world'
6
18
  end
@@ -41,5 +53,10 @@ delete '/delete_with_json' do
41
53
  end
42
54
 
43
55
  get '/multi' do
44
- [200, { 'Set-Cookie' => %w[ one two ] }, '']
56
+ [200, { 'Set-Cookie' => 'one, two' }, '']
57
+ end
58
+
59
+ get '/slow' do
60
+ sleep 10
61
+ [200, {}, 'ok']
45
62
  end
@@ -1,7 +1,8 @@
1
+ # encoding: utf-8
1
2
  require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
2
3
  require 'rack/utils'
3
4
 
4
- Faraday::CompositeReadIO.send :attr_reader, :ios
5
+ Faraday::CompositeReadIO.class_eval { attr_reader :ios }
5
6
 
6
7
  class RequestMiddlewareTest < Faraday::TestCase
7
8
  def setup
@@ -76,7 +77,7 @@ class RequestMiddlewareTest < Faraday::TestCase
76
77
  def test_url_encoded_no_header
77
78
  response = @conn.post('/echo', { :fruit => %w[apples oranges] })
78
79
  assert_equal 'application/x-www-form-urlencoded', response.headers['Content-Type']
79
- assert_equal 'fruit[]=apples&fruit[]=oranges', response.body
80
+ assert_equal 'fruit%5B%5D=apples&fruit%5B%5D=oranges', response.body
80
81
  end
81
82
 
82
83
  def test_url_encoded_with_header
@@ -92,6 +93,19 @@ class RequestMiddlewareTest < Faraday::TestCase
92
93
  assert_equal expected, Rack::Utils.parse_nested_query(response.body)
93
94
  end
94
95
 
96
+ def test_url_encoded_unicode
97
+ err = capture_warnings {
98
+ response = @conn.post('/echo', {:str => "eé cç aã aâ"})
99
+ assert_equal "str=e%C3%A9%20c%C3%A7%20a%C3%A3%20a%C3%A2", response.body
100
+ }
101
+ assert err.empty?
102
+ end
103
+
104
+ def test_url_encoded_nested_keys
105
+ response = @conn.post('/echo', {'a'=>{'b'=>{'c'=>['d']}}})
106
+ assert_equal "a%5Bb%5D%5Bc%5D%5B%5D=d", response.body
107
+ end
108
+
95
109
  def test_multipart
96
110
  # assume params are out of order
97
111
  regexes = [
@@ -113,4 +127,27 @@ class RequestMiddlewareTest < Faraday::TestCase
113
127
  end
114
128
  assert_equal [], regexes
115
129
  end
130
+
131
+ def test_multipart_with_arrays
132
+ # assume params are out of order
133
+ regexes = [
134
+ /name\=\"a\"/,
135
+ /name=\"b\[\]\[c\]\"\; filename\=\"request_middleware_test\.rb\"/,
136
+ /name=\"b\[\]\[d\]\"/]
137
+
138
+ payload = {:a => 1, :b =>[{:c => Faraday::UploadIO.new(__FILE__, 'text/x-ruby'), :d => 2}]}
139
+ response = @conn.post('/echo', payload)
140
+
141
+ assert_kind_of Faraday::CompositeReadIO, response.body
142
+ assert_equal "multipart/form-data;boundary=%s" % Faraday::Request::Multipart::DEFAULT_BOUNDARY,
143
+ response.headers['Content-Type']
144
+
145
+ response.body.send(:ios).map{|io| io.read}.each do |io|
146
+ if re = regexes.detect { |r| io =~ r }
147
+ regexes.delete re
148
+ end
149
+ end
150
+ assert_equal [], regexes
151
+ end
152
+
116
153
  end
@@ -23,7 +23,7 @@ class ResponseMiddlewareTest < Faraday::TestCase
23
23
  @conn.get('ok')
24
24
  end
25
25
  end
26
-
26
+
27
27
  def test_raises_not_found
28
28
  error = assert_raises Faraday::Error::ResourceNotFound do
29
29
  @conn.get('not-found')
@@ -31,7 +31,7 @@ class ResponseMiddlewareTest < Faraday::TestCase
31
31
  assert_equal 'the server responded with status 404', error.message
32
32
  assert_equal 'because', error.response[:headers]['X-Reason']
33
33
  end
34
-
34
+
35
35
  def test_raises_error
36
36
  error = assert_raises Faraday::Error::ClientError do
37
37
  @conn.get('error')
@@ -39,7 +39,7 @@ class ResponseMiddlewareTest < Faraday::TestCase
39
39
  assert_equal 'the server responded with status 500', error.message
40
40
  assert_equal 'bailout', error.response[:headers]['X-Error']
41
41
  end
42
-
42
+
43
43
  def test_upcase
44
44
  @conn.builder.insert(0, ResponseUpcaser)
45
45
  assert_equal '<BODY></BODY>', @conn.get('ok').body
@@ -71,4 +71,4 @@ class ResponseNoBodyMiddleWareTest < Faraday::TestCase
71
71
  def test_304
72
72
  assert_equal nil, @conn.get('not modified').body
73
73
  end
74
- end
74
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faraday
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.5
4
+ version: 0.7.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,77 +9,74 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-04 00:00:00.000000000Z
12
+ date: 2012-01-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: addressable
16
- requirement: &70213347338660 !ruby/object:Gem::Requirement
16
+ requirement: &70207313872560 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 2.2.6
21
+ version: '2.2'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70213347338660
24
+ version_requirements: *70207313872560
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: multipart-post
27
- requirement: &70213347338000 !ruby/object:Gem::Requirement
27
+ requirement: &70207313884640 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
31
31
  - !ruby/object:Gem::Version
32
- version: 1.1.3
32
+ version: '1.1'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70213347338000
35
+ version_requirements: *70207313884640
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rack
38
- requirement: &70213347336580 !ruby/object:Gem::Requirement
38
+ requirement: &70207313889320 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
- - - ! '>='
42
- - !ruby/object:Gem::Version
43
- version: 1.1.0
44
- - - <
41
+ - - ~>
45
42
  - !ruby/object:Gem::Version
46
- version: '2'
43
+ version: '1.1'
47
44
  type: :runtime
48
45
  prerelease: false
49
- version_requirements: *70213347336580
46
+ version_requirements: *70207313889320
50
47
  - !ruby/object:Gem::Dependency
51
48
  name: rake
52
- requirement: &70213347335860 !ruby/object:Gem::Requirement
49
+ requirement: &70207313910400 !ruby/object:Gem::Requirement
53
50
  none: false
54
51
  requirements:
55
- - - ~>
52
+ - - ! '>='
56
53
  - !ruby/object:Gem::Version
57
- version: '0.9'
54
+ version: '0'
58
55
  type: :development
59
56
  prerelease: false
60
- version_requirements: *70213347335860
57
+ version_requirements: *70207313910400
61
58
  - !ruby/object:Gem::Dependency
62
59
  name: test-unit
63
- requirement: &70213347335220 !ruby/object:Gem::Requirement
60
+ requirement: &70207313926400 !ruby/object:Gem::Requirement
64
61
  none: false
65
62
  requirements:
66
- - - ~>
63
+ - - ! '>='
67
64
  - !ruby/object:Gem::Version
68
- version: '2.4'
65
+ version: '0'
69
66
  type: :development
70
67
  prerelease: false
71
- version_requirements: *70213347335220
68
+ version_requirements: *70207313926400
72
69
  - !ruby/object:Gem::Dependency
73
70
  name: webmock
74
- requirement: &70213347334540 !ruby/object:Gem::Requirement
71
+ requirement: &70207313936720 !ruby/object:Gem::Requirement
75
72
  none: false
76
73
  requirements:
77
- - - ~>
74
+ - - ! '>='
78
75
  - !ruby/object:Gem::Version
79
- version: '1.7'
76
+ version: '0'
80
77
  type: :development
81
78
  prerelease: false
82
- version_requirements: *70213347334540
79
+ version_requirements: *70207313936720
83
80
  description: HTTP/REST API client library.
84
81
  email: technoweenie@gmail.com
85
82
  executables: []
@@ -118,6 +115,7 @@ files:
118
115
  - test/adapters/logger_test.rb
119
116
  - test/adapters/net_http_test.rb
120
117
  - test/adapters/test_middleware_test.rb
118
+ - test/adapters/typhoeus_test.rb
121
119
  - test/connection_test.rb
122
120
  - test/env_test.rb
123
121
  - test/helper.rb
@@ -145,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
143
  version: 1.3.5
146
144
  requirements: []
147
145
  rubyforge_project: faraday
148
- rubygems_version: 1.8.10
146
+ rubygems_version: 1.8.12
149
147
  signing_key:
150
148
  specification_version: 2
151
149
  summary: HTTP/REST API client library.
@@ -154,6 +152,7 @@ test_files:
154
152
  - test/adapters/logger_test.rb
155
153
  - test/adapters/net_http_test.rb
156
154
  - test/adapters/test_middleware_test.rb
155
+ - test/adapters/typhoeus_test.rb
157
156
  - test/connection_test.rb
158
157
  - test/env_test.rb
159
158
  - test/helper.rb
@@ -161,3 +160,4 @@ test_files:
161
160
  - test/middleware_stack_test.rb
162
161
  - test/request_middleware_test.rb
163
162
  - test/response_middleware_test.rb
163
+ has_rdoc: