faraday 0.8.11 → 0.9.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. data/.document +6 -0
  2. data/CONTRIBUTING.md +36 -0
  3. data/Gemfile +7 -6
  4. data/LICENSE.md +1 -1
  5. data/README.md +38 -51
  6. data/Rakefile +2 -18
  7. data/faraday.gemspec +34 -0
  8. data/lib/faraday.rb +181 -67
  9. data/lib/faraday/adapter.rb +19 -34
  10. data/lib/faraday/adapter/em_http.rb +24 -10
  11. data/lib/faraday/adapter/em_synchrony.rb +1 -15
  12. data/lib/faraday/adapter/excon.rb +6 -12
  13. data/lib/faraday/adapter/httpclient.rb +92 -0
  14. data/lib/faraday/adapter/net_http.rb +2 -3
  15. data/lib/faraday/adapter/net_http_persistent.rb +3 -15
  16. data/lib/faraday/adapter/patron.rb +13 -21
  17. data/lib/faraday/adapter/rack.rb +0 -2
  18. data/lib/faraday/adapter/test.rb +35 -36
  19. data/lib/faraday/adapter/typhoeus.rb +10 -12
  20. data/lib/faraday/autoload.rb +87 -0
  21. data/lib/faraday/connection.rb +196 -99
  22. data/lib/faraday/error.rb +33 -33
  23. data/lib/faraday/options.rb +215 -0
  24. data/lib/faraday/parameters.rb +193 -0
  25. data/lib/faraday/{builder.rb → rack_builder.rb} +78 -21
  26. data/lib/faraday/request.rb +12 -25
  27. data/lib/faraday/request/authorization.rb +3 -3
  28. data/lib/faraday/request/basic_authentication.rb +1 -1
  29. data/lib/faraday/request/instrumentation.rb +38 -0
  30. data/lib/faraday/request/multipart.rb +10 -9
  31. data/lib/faraday/request/retry.rb +70 -6
  32. data/lib/faraday/request/token_authentication.rb +2 -2
  33. data/lib/faraday/request/url_encoded.rb +7 -6
  34. data/lib/faraday/response.rb +17 -22
  35. data/lib/faraday/response/logger.rb +4 -4
  36. data/lib/faraday/response/raise_error.rb +4 -5
  37. data/lib/faraday/utils.rb +54 -67
  38. data/script/console +7 -0
  39. data/script/release +6 -3
  40. data/script/server +3 -1
  41. data/script/test +7 -33
  42. data/test/adapters/em_http_test.rb +6 -1
  43. data/test/adapters/em_synchrony_test.rb +7 -1
  44. data/test/adapters/excon_test.rb +0 -7
  45. data/test/adapters/httpclient_test.rb +16 -0
  46. data/test/adapters/integration.rb +8 -39
  47. data/test/adapters/logger_test.rb +1 -1
  48. data/test/adapters/net_http_test.rb +0 -31
  49. data/test/adapters/patron_test.rb +1 -1
  50. data/test/adapters/rack_test.rb +0 -5
  51. data/test/adapters/test_middleware_test.rb +19 -4
  52. data/test/adapters/typhoeus_test.rb +20 -3
  53. data/test/authentication_middleware_test.rb +7 -7
  54. data/test/connection_test.rb +52 -75
  55. data/test/env_test.rb +33 -24
  56. data/test/helper.rb +15 -13
  57. data/test/live_server.rb +10 -4
  58. data/test/middleware/instrumentation_test.rb +75 -0
  59. data/test/middleware/retry_test.rb +44 -38
  60. data/test/middleware_stack_test.rb +12 -11
  61. data/test/options_test.rb +126 -0
  62. data/test/request_middleware_test.rb +17 -7
  63. data/test/response_middleware_test.rb +2 -4
  64. data/test/strawberry.rb +2 -0
  65. metadata +82 -28
  66. checksums.yaml +0 -7
  67. data/script/proxy-server +0 -41
  68. data/test/multibyte.txt +0 -1
  69. data/test/parameters_test.rb +0 -24
  70. data/test/utils_test.rb +0 -30
@@ -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
  class EnvTest < Faraday::TestCase
4
4
  def setup
@@ -6,29 +6,29 @@ class EnvTest < Faraday::TestCase
6
6
  :headers => {'Mime-Version' => '1.0'},
7
7
  :request => {:oauth => {:consumer_key => 'anonymous'}}
8
8
 
9
- @conn.options[:timeout] = 3
10
- @conn.options[:open_timeout] = 5
11
- @conn.ssl[:verify] = false
9
+ @conn.options.timeout = 3
10
+ @conn.options.open_timeout = 5
11
+ @conn.ssl.verify = false
12
12
  @conn.proxy 'http://proxy.com'
13
13
  end
14
14
 
15
15
  def test_request_create_stores_method
16
16
  env = make_env(:get)
17
- assert_equal :get, env[:method]
17
+ assert_equal :get, env.method
18
18
  end
19
19
 
20
20
  def test_request_create_stores_uri
21
21
  env = make_env do |req|
22
22
  req.url 'foo.json', 'a' => 1
23
23
  end
24
- assert_equal 'http://sushi.com/api/foo.json?a=1', env[:url].to_s
24
+ assert_equal 'http://sushi.com/api/foo.json?a=1', env.url.to_s
25
25
  end
26
26
 
27
27
  def test_request_create_stores_headers
28
28
  env = make_env do |req|
29
29
  req['Server'] = 'Faraday'
30
30
  end
31
- headers = env[:request_headers]
31
+ headers = env.request_headers
32
32
  assert_equal '1.0', headers['mime-version']
33
33
  assert_equal 'Faraday', headers['server']
34
34
  end
@@ -37,37 +37,37 @@ class EnvTest < Faraday::TestCase
37
37
  env = make_env do |req|
38
38
  req.body = 'hi'
39
39
  end
40
- assert_equal 'hi', env[:body]
40
+ assert_equal 'hi', env.body
41
41
  end
42
42
 
43
43
  def test_global_request_options
44
44
  env = make_env
45
- assert_equal 3, env[:request][:timeout]
46
- assert_equal 5, env[:request][:open_timeout]
45
+ assert_equal 3, env.request.timeout
46
+ assert_equal 5, env.request.open_timeout
47
47
  end
48
48
 
49
49
  def test_per_request_options
50
50
  env = make_env do |req|
51
- req.options[:timeout] = 10
52
- req.options[:custom] = true
53
- req.options[:oauth][:consumer_secret] = 'xyz'
51
+ req.options.timeout = 10
52
+ req.options.boundary = 'boo'
53
+ req.options.oauth[:consumer_secret] = 'xyz'
54
54
  end
55
- assert_equal 10, env[:request][:timeout]
56
- assert_equal 5, env[:request][:open_timeout]
57
- assert_equal true, env[:request][:custom]
55
+ assert_equal 10, env.request.timeout
56
+ assert_equal 5, env.request.open_timeout
57
+ assert_equal 'boo', env.request.boundary
58
58
 
59
59
  oauth_expected = {:consumer_secret => 'xyz', :consumer_key => 'anonymous'}
60
- assert_equal oauth_expected, env[:request][:oauth]
60
+ assert_equal oauth_expected, env.request.oauth
61
61
  end
62
62
 
63
63
  def test_request_create_stores_ssl_options
64
64
  env = make_env
65
- assert_equal false, env[:ssl][:verify]
65
+ assert_equal false, env.ssl.verify
66
66
  end
67
67
 
68
68
  def test_request_create_stores_proxy_options
69
69
  env = make_env
70
- assert_equal 'proxy.com', env[:request][:proxy][:uri].host
70
+ assert_equal 'proxy.com', env.request.proxy.host
71
71
  end
72
72
 
73
73
  private
@@ -131,10 +131,9 @@ end
131
131
 
132
132
  class ResponseTest < Faraday::TestCase
133
133
  def setup
134
- @env = {
134
+ @env = Faraday::Env.from \
135
135
  :status => 404, :body => 'yikes',
136
- :response_headers => Faraday::Utils::Headers.new('Content-Type' => 'text/plain')
137
- }
136
+ :response_headers => {'Content-Type' => 'text/plain'}
138
137
  @response = Faraday::Response.new @env
139
138
  end
140
139
 
@@ -174,10 +173,20 @@ class ResponseTest < Faraday::TestCase
174
173
  def test_marshal
175
174
  @response = Faraday::Response.new
176
175
  @response.on_complete { }
177
- @response.finish @env.merge(:custom => 'moo')
176
+ @response.finish @env.merge(:params => 'moo')
178
177
 
179
178
  loaded = Marshal.load Marshal.dump(@response)
180
- assert_nil loaded.env[:custom]
179
+ assert_nil loaded.env[:params]
181
180
  assert_equal %w[body response_headers status], loaded.env.keys.map { |k| k.to_s }.sort
182
181
  end
182
+
183
+ def test_hash
184
+ hash = @response.to_hash
185
+ assert_kind_of Hash, hash
186
+ assert_equal @env.to_hash, hash
187
+ assert_equal hash[:status], @response.status
188
+ assert_equal hash[:response_headers], @response.headers
189
+ assert_equal hash[:body], @response.body
190
+ end
183
191
  end
192
+
@@ -1,14 +1,17 @@
1
- if RUBY_VERSION >= '1.9'
2
- require 'simplecov'
1
+ require 'rubygems' # rubygems/version doesn't work by itself
2
+ require 'rubygems/version' # for simplecov-html
3
+ require 'simplecov'
4
+ require 'coveralls'
3
5
 
4
- SimpleCov.start do
5
- add_filter '/bundle/'
6
- add_filter '/test/'
7
- minimum_coverage(88.74)
8
- end
6
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
7
+ SimpleCov::Formatter::HTMLFormatter,
8
+ Coveralls::SimpleCov::Formatter
9
+ ]
10
+ SimpleCov.start do
11
+ add_filter '/bundle/'
9
12
  end
10
13
 
11
- require 'test/unit'
14
+ require 'minitest/autorun'
12
15
 
13
16
  if ENV['LEFTRIGHT']
14
17
  begin
@@ -19,6 +22,9 @@ if ENV['LEFTRIGHT']
19
22
  end
20
23
 
21
24
  require File.expand_path('../../lib/faraday', __FILE__)
25
+ Dir[File.expand_path('../../lib/faraday/r*/*', __FILE__)].each do |file|
26
+ require file
27
+ end
22
28
 
23
29
  require 'stringio'
24
30
  require 'uri'
@@ -44,7 +50,7 @@ module Faraday
44
50
  end
45
51
  end
46
52
 
47
- class TestCase < Test::Unit::TestCase
53
+ class TestCase < MiniTest::Unit::TestCase
48
54
  extend LiveServerConfig
49
55
  self.live_server = ENV['LIVE']
50
56
 
@@ -70,10 +76,6 @@ module Faraday
70
76
  defined? RUBY_ENGINE and 'rbx' == RUBY_ENGINE
71
77
  end
72
78
 
73
- def self.ruby_22_plus?
74
- RUBY_VERSION > '2.2'
75
- end
76
-
77
79
  def self.ssl_mode?
78
80
  ENV['SSL'] == 'yes'
79
81
  end
@@ -25,11 +25,9 @@ class LiveServer < Sinatra::Base
25
25
 
26
26
  post '/file' do
27
27
  if params[:uploaded_file].respond_to? :each_key
28
- "file %s %s %d" % [
28
+ "file %s %s" % [
29
29
  params[:uploaded_file][:filename],
30
- params[:uploaded_file][:type],
31
- params[:uploaded_file][:tempfile].size
32
- ]
30
+ params[:uploaded_file][:type]]
33
31
  else
34
32
  status 400
35
33
  end
@@ -39,11 +37,19 @@ class LiveServer < Sinatra::Base
39
37
  [200, { 'Set-Cookie' => 'one, two' }, '']
40
38
  end
41
39
 
40
+ get '/who-am-i' do
41
+ request.env['REMOTE_ADDR']
42
+ end
43
+
42
44
  get '/slow' do
43
45
  sleep 10
44
46
  [200, {}, 'ok']
45
47
  end
46
48
 
49
+ get '/204' do
50
+ status 204 # no content
51
+ end
52
+
47
53
  get '/ssl' do
48
54
  request.secure?.to_s
49
55
  end
@@ -0,0 +1,75 @@
1
+ require File.expand_path("../../helper", __FILE__)
2
+
3
+ module Middleware
4
+ class InstrumentationTest < Faraday::TestCase
5
+ def setup
6
+ @instrumenter = FakeInstrumenter.new
7
+ end
8
+
9
+ def test_default_name
10
+ assert_equal 'request.faraday', options.name
11
+ end
12
+
13
+ def test_default_instrumenter
14
+ begin
15
+ instrumenter = options.instrumenter
16
+ rescue NameError => err
17
+ assert_match 'ActiveSupport', err.to_s
18
+ else
19
+ assert_equal ActiveSupport::Notifications, instrumenter
20
+ end
21
+ end
22
+
23
+ def test_name
24
+ assert_equal 'booya', options(:name => 'booya').name
25
+ end
26
+
27
+ def test_instrumenter
28
+ assert_equal :boom, options(:instrumenter => :boom).instrumenter
29
+ end
30
+
31
+ def test_instrumentation
32
+ assert_equal 0, @instrumenter.instrumentations.size
33
+
34
+ faraday = conn :name => 'booya'
35
+ res = faraday.get '/'
36
+ assert_equal 'ok', res.body
37
+
38
+ assert_equal 1, @instrumenter.instrumentations.size
39
+ name, env = @instrumenter.instrumentations.first
40
+ assert_equal 'booya', name
41
+ assert_equal '/', env[:url].path
42
+ end
43
+
44
+ class FakeInstrumenter
45
+ attr_reader :instrumentations
46
+
47
+ def initialize
48
+ @instrumentations = []
49
+ end
50
+
51
+ def instrument(name, env)
52
+ @instrumentations << [name, env]
53
+ yield
54
+ end
55
+ end
56
+
57
+ def options(hash = nil)
58
+ Faraday::Request::Instrumentation::Options.from hash
59
+ end
60
+
61
+ def conn(hash = nil)
62
+ hash ||= {}
63
+ hash[:instrumenter] = @instrumenter
64
+
65
+ Faraday.new do |f|
66
+ f.request :instrumentation, hash
67
+ f.adapter :test do |stub|
68
+ stub.get '/' do
69
+ [200, {}, 'ok']
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,56 +1,62 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), "..", "helper"))
1
+ require File.expand_path("../../helper", __FILE__)
2
2
 
3
3
  module Middleware
4
4
  class RetryTest < Faraday::TestCase
5
5
  def setup
6
- @stubs = Faraday::Adapter::Test::Stubs.new
7
- @conn = Faraday.new do |b|
8
- b.request :retry, 2
9
- b.use ContentValidator
10
- b.adapter :test, @stubs
11
- end
6
+ @times_called = 0
12
7
  end
13
8
 
14
- ContentValidator = Struct.new(:app) do
15
- def call(env)
16
- response = app.call(env)
17
- type = response[:content_type]
18
- raise "wrong content-type: %p" % type unless type == "application/json"
9
+ def conn(*retry_args)
10
+ Faraday.new do |b|
11
+ b.request :retry, *retry_args
12
+ b.adapter :test do |stub|
13
+ stub.post('/unstable') {
14
+ @times_called += 1
15
+ @explode.call @times_called
16
+ }
17
+ end
19
18
  end
20
19
  end
21
20
 
22
- def test_retries
23
- times_called = 0
24
-
25
- @stubs.post("/echo") do
26
- times_called += 1
27
- [200, {}, "hello"]
28
- end
21
+ def test_unhandled_error
22
+ @explode = lambda {|n| raise "boom!" }
23
+ assert_raises(RuntimeError) { conn.post("/unstable") }
24
+ assert_equal 1, @times_called
25
+ end
29
26
 
30
- @conn.post("/echo") rescue nil
31
- assert_equal times_called, 3
27
+ def test_handled_error
28
+ @explode = lambda {|n| raise Errno::ETIMEDOUT }
29
+ assert_raises(Errno::ETIMEDOUT) { conn.post("/unstable") }
30
+ assert_equal 3, @times_called
32
31
  end
33
32
 
34
- def test_retry_with_body
35
- times_called = 0
36
- bodies_received = []
33
+ def test_legacy_max_retries
34
+ @explode = lambda {|n| raise Errno::ETIMEDOUT }
35
+ assert_raises(Errno::ETIMEDOUT) { conn(1).post("/unstable") }
36
+ assert_equal 2, @times_called
37
+ end
37
38
 
38
- @stubs.post("/echo") do |env|
39
- times_called += 1
40
- bodies_received << env[:body]
41
- if times_called < 2
42
- [200, {"Content-type" => "text/plain"}, "hello"]
43
- else
44
- [200, {"Content-type" => "application/json"}, '{"message": "hello"}']
45
- end
46
- end
39
+ def test_new_max_retries
40
+ @explode = lambda {|n| raise Errno::ETIMEDOUT }
41
+ assert_raises(Errno::ETIMEDOUT) { conn(:max => 3).post("/unstable") }
42
+ assert_equal 4, @times_called
43
+ end
47
44
 
48
- body = {:foo => "bar"}
49
- @conn.post("/echo", body)
45
+ def test_interval
46
+ @explode = lambda {|n| raise Errno::ETIMEDOUT }
47
+ started = Time.now
48
+ assert_raises(Errno::ETIMEDOUT) {
49
+ conn(:max => 2, :interval => 0.1).post("/unstable")
50
+ }
51
+ assert_in_delta 0.2, Time.now - started, 0.03
52
+ end
50
53
 
51
- assert_equal times_called, 2
52
- assert_same body, bodies_received[0]
53
- assert_same body, bodies_received[1]
54
+ def test_custom_exceptions
55
+ @explode = lambda {|n| raise "boom!" }
56
+ assert_raises(RuntimeError) {
57
+ conn(:exceptions => StandardError).post("/unstable")
58
+ }
59
+ assert_equal 3, @times_called
54
60
  end
55
61
  end
56
62
  end
@@ -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
  class MiddlewareStackTest < Faraday::TestCase
4
4
  # mock handler classes
@@ -75,7 +75,7 @@ class MiddlewareStackTest < Faraday::TestCase
75
75
  @conn.get('/')
76
76
  assert @builder.locked?
77
77
 
78
- assert_raises Faraday::Builder::StackLocked do
78
+ assert_raises Faraday::RackBuilder::StackLocked do
79
79
  @conn.use Orange
80
80
  end
81
81
  end
@@ -95,16 +95,16 @@ class MiddlewareStackTest < Faraday::TestCase
95
95
  build_stack Apple
96
96
  assert_equal @builder.handlers.first, Apple
97
97
  assert_equal @builder.handlers[0,1], [Apple]
98
- assert_equal @builder.handlers.first, Faraday::Builder::Handler.new(Apple)
98
+ assert_equal @builder.handlers.first, Faraday::RackBuilder::Handler.new(Apple)
99
99
  end
100
100
 
101
101
  def test_unregistered_symbol
102
- err = assert_raise(RuntimeError) { build_stack :apple }
102
+ err = assert_raises(Faraday::Error){ build_stack :apple }
103
103
  assert_equal ":apple is not registered on Faraday::Middleware", err.message
104
104
  end
105
105
 
106
106
  def test_registered_symbol
107
- Faraday.register_middleware :apple => Apple
107
+ Faraday::Middleware.register_middleware :apple => Apple
108
108
  begin
109
109
  build_stack :apple
110
110
  assert_handlers %w[Apple]
@@ -114,7 +114,7 @@ class MiddlewareStackTest < Faraday::TestCase
114
114
  end
115
115
 
116
116
  def test_registered_symbol_with_proc
117
- Faraday.register_middleware :apple => lambda { Apple }
117
+ Faraday::Middleware.register_middleware :apple => lambda { Apple }
118
118
  begin
119
119
  build_stack :apple
120
120
  assert_handlers %w[Apple]
@@ -123,13 +123,14 @@ class MiddlewareStackTest < Faraday::TestCase
123
123
  end
124
124
  end
125
125
 
126
- def test_registered_symbol_with_type
127
- Faraday.register_middleware :request, :orange => Orange
126
+ def test_registered_symbol_with_array
127
+ Faraday::Middleware.register_middleware File.expand_path("..", __FILE__),
128
+ :strawberry => [lambda { Strawberry }, 'strawberry']
128
129
  begin
129
- build_stack {|b| b.request :orange }
130
- assert_handlers %w[Orange]
130
+ build_stack :strawberry
131
+ assert_handlers %w[Strawberry]
131
132
  ensure
132
- unregister_middleware Faraday::Request, :orange
133
+ unregister_middleware Faraday::Middleware, :strawberry
133
134
  end
134
135
  end
135
136