faraday 0.9.1 → 0.17.1

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 (74) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +196 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +192 -28
  5. data/Rakefile +6 -64
  6. data/lib/faraday/adapter/em_http.rb +17 -11
  7. data/lib/faraday/adapter/em_http_ssl_patch.rb +1 -1
  8. data/lib/faraday/adapter/em_synchrony.rb +19 -5
  9. data/lib/faraday/adapter/excon.rb +13 -11
  10. data/lib/faraday/adapter/httpclient.rb +31 -9
  11. data/lib/faraday/adapter/net_http.rb +36 -14
  12. data/lib/faraday/adapter/net_http_persistent.rb +37 -17
  13. data/lib/faraday/adapter/patron.rb +44 -21
  14. data/lib/faraday/adapter/rack.rb +1 -1
  15. data/lib/faraday/adapter/test.rb +79 -28
  16. data/lib/faraday/adapter/typhoeus.rb +4 -115
  17. data/lib/faraday/adapter.rb +10 -1
  18. data/lib/faraday/autoload.rb +1 -1
  19. data/lib/faraday/connection.rb +72 -20
  20. data/lib/faraday/deprecate.rb +101 -0
  21. data/lib/faraday/error.rb +90 -24
  22. data/lib/faraday/options.rb +43 -20
  23. data/lib/faraday/parameters.rb +56 -39
  24. data/lib/faraday/rack_builder.rb +27 -2
  25. data/lib/faraday/request/authorization.rb +1 -2
  26. data/lib/faraday/request/multipart.rb +7 -2
  27. data/lib/faraday/request/retry.rb +84 -19
  28. data/lib/faraday/request.rb +22 -0
  29. data/lib/faraday/response/logger.rb +29 -8
  30. data/lib/faraday/response/raise_error.rb +7 -3
  31. data/lib/faraday/response.rb +9 -5
  32. data/lib/faraday/utils.rb +32 -3
  33. data/lib/faraday.rb +14 -34
  34. data/spec/faraday/deprecate_spec.rb +69 -0
  35. data/spec/faraday/error_spec.rb +102 -0
  36. data/spec/faraday/response/raise_error_spec.rb +95 -0
  37. data/spec/spec_helper.rb +104 -0
  38. data/test/adapters/em_http_test.rb +10 -0
  39. data/test/adapters/em_synchrony_test.rb +22 -10
  40. data/test/adapters/excon_test.rb +10 -0
  41. data/test/adapters/httpclient_test.rb +14 -1
  42. data/test/adapters/integration.rb +17 -8
  43. data/test/adapters/logger_test.rb +65 -11
  44. data/test/adapters/net_http_persistent_test.rb +96 -2
  45. data/test/adapters/net_http_test.rb +67 -2
  46. data/test/adapters/patron_test.rb +28 -8
  47. data/test/adapters/rack_test.rb +8 -1
  48. data/test/adapters/test_middleware_test.rb +46 -3
  49. data/test/adapters/typhoeus_test.rb +19 -9
  50. data/test/composite_read_io_test.rb +16 -18
  51. data/test/connection_test.rb +294 -78
  52. data/test/env_test.rb +55 -5
  53. data/test/helper.rb +11 -17
  54. data/test/middleware/retry_test.rb +115 -10
  55. data/test/middleware_stack_test.rb +97 -10
  56. data/test/options_test.rb +97 -16
  57. data/test/parameters_test.rb +94 -1
  58. data/test/request_middleware_test.rb +24 -40
  59. data/test/response_middleware_test.rb +4 -4
  60. data/test/utils_test.rb +40 -0
  61. metadata +21 -66
  62. data/.document +0 -6
  63. data/CONTRIBUTING.md +0 -36
  64. data/Gemfile +0 -25
  65. data/faraday.gemspec +0 -34
  66. data/script/cached-bundle +0 -46
  67. data/script/console +0 -7
  68. data/script/generate_certs +0 -42
  69. data/script/package +0 -7
  70. data/script/proxy-server +0 -42
  71. data/script/release +0 -17
  72. data/script/s3-put +0 -71
  73. data/script/server +0 -36
  74. data/script/test +0 -172
data/test/env_test.rb CHANGED
@@ -9,7 +9,7 @@ class EnvTest < Faraday::TestCase
9
9
  @conn.options.timeout = 3
10
10
  @conn.options.open_timeout = 5
11
11
  @conn.ssl.verify = false
12
- @conn.proxy 'http://proxy.com'
12
+ @conn.proxy = 'http://proxy.com'
13
13
  end
14
14
 
15
15
  def test_request_create_stores_method
@@ -24,6 +24,13 @@ class EnvTest < Faraday::TestCase
24
24
  assert_equal 'http://sushi.com/api/foo.json?a=1', env.url.to_s
25
25
  end
26
26
 
27
+ def test_request_create_stores_uri_with_anchor
28
+ env = make_env do |req|
29
+ req.url 'foo.json?b=2&a=1#qqq'
30
+ end
31
+ assert_equal 'http://sushi.com/api/foo.json?a=1&b=2', env.url.to_s
32
+ end
33
+
27
34
  def test_request_create_stores_headers
28
35
  env = make_env do |req|
29
36
  req['Server'] = 'Faraday'
@@ -51,10 +58,16 @@ class EnvTest < Faraday::TestCase
51
58
  req.options.timeout = 10
52
59
  req.options.boundary = 'boo'
53
60
  req.options.oauth[:consumer_secret] = 'xyz'
61
+ req.options.context = {
62
+ foo: 'foo',
63
+ bar: 'bar'
64
+ }
54
65
  end
66
+
55
67
  assert_equal 10, env.request.timeout
56
68
  assert_equal 5, env.request.open_timeout
57
69
  assert_equal 'boo', env.request.boundary
70
+ assert_equal env.request.context, { foo: 'foo', bar: 'bar' }
58
71
 
59
72
  oauth_expected = {:consumer_secret => 'xyz', :consumer_key => 'anonymous'}
60
73
  assert_equal oauth_expected, env.request.oauth
@@ -65,9 +78,15 @@ class EnvTest < Faraday::TestCase
65
78
  assert_equal false, env.ssl.verify
66
79
  end
67
80
 
68
- def test_request_create_stores_proxy_options
81
+ def test_custom_members_are_retained
69
82
  env = make_env
70
- assert_equal 'proxy.com', env.request.proxy.host
83
+ env[:foo] = "custom 1"
84
+ env[:bar] = :custom_2
85
+ env2 = Faraday::Env.from(env)
86
+ assert_equal "custom 1", env2[:foo]
87
+ assert_equal :custom_2, env2[:bar]
88
+ env2[:baz] = "custom 3"
89
+ assert_nil env[:baz]
71
90
  end
72
91
 
73
92
  private
@@ -124,7 +143,7 @@ class HeadersTest < Faraday::TestCase
124
143
  assert_equal 'application/json', @headers.delete('content-type')
125
144
  assert_equal 0, @headers.size
126
145
  assert !@headers.include?('content-type')
127
- assert_equal nil, @headers.delete('content-type')
146
+ assert_nil @headers.delete('content-type')
128
147
  end
129
148
 
130
149
  def test_parse_response_headers_leaves_http_status_line_out
@@ -174,6 +193,23 @@ class ResponseTest < Faraday::TestCase
174
193
  assert_equal "YIKES", response.body
175
194
  end
176
195
 
196
+ def test_response_body_is_available_during_on_complete
197
+ response = Faraday::Response.new
198
+ response.on_complete { |env| env[:body] = response.body.upcase }
199
+ response.finish(@env)
200
+
201
+ assert_equal "YIKES", response.body
202
+ end
203
+
204
+ def test_env_in_on_complete_is_identical_to_response_env
205
+ response = Faraday::Response.new
206
+ callback_env = nil
207
+ response.on_complete { |env| callback_env = env }
208
+ response.finish({})
209
+
210
+ assert_same response.env, callback_env
211
+ end
212
+
177
213
  def test_not_success
178
214
  assert !@response.success?
179
215
  end
@@ -197,7 +233,7 @@ class ResponseTest < Faraday::TestCase
197
233
  assert_equal :post, @response.env[:method]
198
234
  end
199
235
 
200
- def test_marshal
236
+ def test_marshal_response
201
237
  @response = Faraday::Response.new
202
238
  @response.on_complete { }
203
239
  @response.finish @env.merge(:params => 'moo')
@@ -207,6 +243,20 @@ class ResponseTest < Faraday::TestCase
207
243
  assert_equal %w[body response_headers status], loaded.env.keys.map { |k| k.to_s }.sort
208
244
  end
209
245
 
246
+ def test_marshal_request
247
+ @request = Faraday::Request.create(:post) do |request|
248
+ request.options = Faraday::RequestOptions.new
249
+ request.params = Faraday::Utils::ParamsHash.new({ 'a' => 'c' })
250
+ request.headers = { 'b' => 'd' }
251
+ request.body = 'hello, world!'
252
+ request.url 'http://localhost/foo'
253
+ end
254
+
255
+ loaded = Marshal.load(Marshal.dump(@request))
256
+
257
+ assert_equal @request, loaded
258
+ end
259
+
210
260
  def test_hash
211
261
  hash = @response.to_hash
212
262
  assert_kind_of Hash, hash
data/test/helper.rb CHANGED
@@ -1,27 +1,17 @@
1
- if RUBY_VERSION >= '1.9'
2
- require 'simplecov'
3
- require 'coveralls'
1
+ require 'simplecov'
2
+ require 'coveralls'
4
3
 
5
- SimpleCov.formatters = [SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter]
4
+ SimpleCov.formatters = [SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter]
6
5
 
7
- SimpleCov.start do
8
- add_filter '/bundle/'
9
- add_filter '/test/'
10
- minimum_coverage(87.27)
11
- end
6
+ SimpleCov.start do
7
+ add_filter '/bundle/'
8
+ add_filter '/test/'
9
+ minimum_coverage(87)
12
10
  end
13
11
 
14
12
  gem 'minitest' if defined? Bundler
15
13
  require 'minitest/autorun'
16
14
 
17
- if ENV['LEFTRIGHT']
18
- begin
19
- require 'leftright'
20
- rescue LoadError
21
- puts "Run `gem install leftright` to install leftright."
22
- end
23
- end
24
-
25
15
  require File.expand_path('../../lib/faraday', __FILE__)
26
16
 
27
17
  require 'stringio'
@@ -74,6 +64,10 @@ module Faraday
74
64
  defined? RUBY_ENGINE and 'rbx' == RUBY_ENGINE
75
65
  end
76
66
 
67
+ def self.ruby_22_plus?
68
+ RUBY_VERSION > '2.2'
69
+ end
70
+
77
71
  def self.ssl_mode?
78
72
  ENV['SSL'] == 'yes'
79
73
  end
@@ -4,17 +4,37 @@ module Middleware
4
4
  class RetryTest < Faraday::TestCase
5
5
  def setup
6
6
  @times_called = 0
7
+ @envs = []
7
8
  end
8
9
 
9
10
  def conn(*retry_args)
10
11
  Faraday.new do |b|
11
12
  b.request :retry, *retry_args
13
+
12
14
  b.adapter :test do |stub|
13
15
  ['get', 'post'].each do |method|
14
- stub.send(method, '/unstable') {
16
+ stub.send(method, '/unstable') do |env|
15
17
  @times_called += 1
18
+ @envs << env.dup
19
+ env[:body] = nil # simulate blanking out response body
16
20
  @explode.call @times_called
17
- }
21
+ end
22
+
23
+ stub.send(method, '/throttled') do |env|
24
+ @times_called += 1
25
+ @envs << env.dup
26
+
27
+ params = env[:params]
28
+
29
+ status = (params['status'] || 429).to_i
30
+ headers = {}
31
+
32
+ retry_after = params['retry_after']
33
+
34
+ headers['Retry-After'] = retry_after if retry_after
35
+
36
+ [status, headers, '']
37
+ end
18
38
  end
19
39
  end
20
40
  end
@@ -65,7 +85,7 @@ module Middleware
65
85
  assert_in_delta 0.2, Time.now - started, 0.04
66
86
  end
67
87
 
68
- def test_calls_sleep_amount
88
+ def test_calls_calculate_sleep_amount
69
89
  explode_app = MiniTest::Mock.new
70
90
  explode_app.expect(:call, nil, [{:body=>nil}])
71
91
  def explode_app.call(env)
@@ -76,7 +96,7 @@ module Middleware
76
96
  class << retry_middleware
77
97
  attr_accessor :sleep_amount_retries
78
98
 
79
- def sleep_amount(retries)
99
+ def calculate_sleep_amount(retries, env)
80
100
  self.sleep_amount_retries.delete(retries)
81
101
  0
82
102
  end
@@ -92,22 +112,30 @@ module Middleware
92
112
 
93
113
  def test_exponential_backoff
94
114
  middleware = Faraday::Request::Retry.new(nil, :max => 5, :interval => 0.1, :backoff_factor => 2)
95
- assert_equal middleware.sleep_amount(5), 0.1
96
- assert_equal middleware.sleep_amount(4), 0.2
97
- assert_equal middleware.sleep_amount(3), 0.4
115
+ assert_equal middleware.send(:calculate_retry_interval, 5), 0.1
116
+ assert_equal middleware.send(:calculate_retry_interval, 4), 0.2
117
+ assert_equal middleware.send(:calculate_retry_interval, 3), 0.4
118
+ end
119
+
120
+ def test_exponential_backoff_with_max_interval
121
+ middleware = Faraday::Request::Retry.new(nil, :max => 5, :interval => 1, :max_interval => 3, :backoff_factor => 2)
122
+ assert_equal middleware.send(:calculate_retry_interval, 5), 1
123
+ assert_equal middleware.send(:calculate_retry_interval, 4), 2
124
+ assert_equal middleware.send(:calculate_retry_interval, 3), 3
125
+ assert_equal middleware.send(:calculate_retry_interval, 2), 3
98
126
  end
99
127
 
100
128
  def test_random_additional_interval_amount
101
129
  middleware = Faraday::Request::Retry.new(nil, :max => 2, :interval => 0.1, :interval_randomness => 1.0)
102
- sleep_amount = middleware.sleep_amount(2)
130
+ sleep_amount = middleware.send(:calculate_retry_interval, 2)
103
131
  assert_operator sleep_amount, :>=, 0.1
104
132
  assert_operator sleep_amount, :<=, 0.2
105
133
  middleware = Faraday::Request::Retry.new(nil, :max => 2, :interval => 0.1, :interval_randomness => 0.5)
106
- sleep_amount = middleware.sleep_amount(2)
134
+ sleep_amount = middleware.send(:calculate_retry_interval, 2)
107
135
  assert_operator sleep_amount, :>=, 0.1
108
136
  assert_operator sleep_amount, :<=, 0.15
109
137
  middleware = Faraday::Request::Retry.new(nil, :max => 2, :interval => 0.1, :interval_randomness => 0.25)
110
- sleep_amount = middleware.sleep_amount(2)
138
+ sleep_amount = middleware.send(:calculate_retry_interval, 2)
111
139
  assert_operator sleep_amount, :>=, 0.1
112
140
  assert_operator sleep_amount, :<=, 0.125
113
141
  end
@@ -120,6 +148,17 @@ module Middleware
120
148
  assert_equal 3, @times_called
121
149
  end
122
150
 
151
+ def test_should_retry_with_body_if_block_returns_true_for_non_idempotent_request
152
+ body = { :foo => :bar }
153
+ @explode = lambda {|n| raise Errno::ETIMEDOUT }
154
+ check = lambda { |env,exception| true }
155
+ assert_raises(Errno::ETIMEDOUT) {
156
+ conn(:retry_if => check).post("/unstable", body)
157
+ }
158
+ assert_equal 3, @times_called
159
+ assert @envs.all? { |env| env[:body] === body }
160
+ end
161
+
123
162
  def test_should_stop_retrying_if_block_returns_false_checking_env
124
163
  @explode = lambda {|n| raise Errno::ETIMEDOUT }
125
164
  check = lambda { |env,exception| env[:method] != :post }
@@ -173,5 +212,71 @@ module Middleware
173
212
  assert_equal 2, @times_called
174
213
  end
175
214
 
215
+ def test_should_rewind_files_on_retry
216
+ io = StringIO.new("Test data")
217
+ upload_io = Faraday::UploadIO.new(io, "application/octet/stream")
218
+
219
+ rewound = 0
220
+ rewind = lambda { rewound += 1 }
221
+
222
+ upload_io.stub :rewind, rewind do
223
+ @explode = lambda {|n| raise Errno::ETIMEDOUT }
224
+ check = lambda { |env,exception| true }
225
+ assert_raises(Errno::ETIMEDOUT) {
226
+ conn(:retry_if => check).post("/unstable", { :file => upload_io })
227
+ }
228
+ end
229
+ assert_equal 3, @times_called
230
+ assert_equal 2, rewound
231
+ end
232
+
233
+ def test_should_retry_retriable_response
234
+ params = { status: 429 }
235
+ response = conn(:max => 1, :retry_statuses => 429).get("/throttled", params)
236
+
237
+ assert_equal 2, @times_called
238
+ assert_equal 429, response.status
239
+ end
240
+
241
+ def test_should_not_retry_non_retriable_response
242
+ params = { status: 503 }
243
+ conn(:max => 1, :retry_statuses => 429).get("/throttled", params)
244
+
245
+ assert_equal 1, @times_called
246
+ end
247
+
248
+ def test_interval_if_retry_after_present
249
+ started = Time.now
250
+
251
+ params = { :retry_after => 0.5 }
252
+ conn(:max => 1, :interval => 0.1, :retry_statuses => [429]).get("/throttled", params)
253
+
254
+ assert Time.now - started > 0.5
255
+ end
256
+
257
+ def test_should_ignore_retry_after_if_less_then_calculated
258
+ started = Time.now
259
+
260
+ params = { :retry_after => 0.1 }
261
+ conn(:max => 1, :interval => 0.2, :retry_statuses => [429]).get("/throttled", params)
262
+
263
+ assert Time.now - started > 0.2
264
+ end
265
+
266
+ def test_interval_when_retry_after_is_timestamp
267
+ started = Time.now
268
+
269
+ params = { :retry_after => (Time.now.utc + 2).strftime('%a, %d %b %Y %H:%M:%S GMT') }
270
+ conn(:max => 1, :interval => 0.1, :retry_statuses => [429]).get("/throttled", params)
271
+
272
+ assert Time.now - started > 1
273
+ end
274
+
275
+ def test_should_not_retry_when_retry_after_greater_then_max_interval
276
+ params = { :retry_after => (Time.now.utc + 20).strftime('%a, %d %b %Y %H:%M:%S GMT') }
277
+ conn(:max => 2, :interval => 0.1, :retry_statuses => [429], max_interval: 5).get("/throttled", params)
278
+
279
+ assert_equal 1, @times_called
280
+ end
176
281
  end
177
282
  end
@@ -35,8 +35,9 @@ class MiddlewareStackTest < Faraday::TestCase
35
35
  end
36
36
 
37
37
  def test_allows_extending
38
- build_stack Apple
39
- @conn.use Orange
38
+ build_handlers_stack Apple
39
+ @builder.use Orange
40
+ @builder.adapter :test, &test_adapter
40
41
  assert_handlers %w[Apple Orange]
41
42
  end
42
43
 
@@ -46,20 +47,23 @@ class MiddlewareStackTest < Faraday::TestCase
46
47
  end
47
48
 
48
49
  def test_insert_before
49
- build_stack Apple, Orange
50
+ build_handlers_stack Apple, Orange
50
51
  @builder.insert_before Apple, Banana
52
+ @builder.adapter :test, &test_adapter
51
53
  assert_handlers %w[Banana Apple Orange]
52
54
  end
53
55
 
54
56
  def test_insert_after
55
- build_stack Apple, Orange
57
+ build_handlers_stack Apple, Orange
56
58
  @builder.insert_after Apple, Banana
59
+ @builder.adapter :test, &test_adapter
57
60
  assert_handlers %w[Apple Banana Orange]
58
61
  end
59
62
 
60
63
  def test_swap_handlers
61
- build_stack Apple, Orange
64
+ build_handlers_stack Apple, Orange
62
65
  @builder.swap Apple, Banana
66
+ @builder.adapter :test, &test_adapter
63
67
  assert_handlers %w[Banana Orange]
64
68
  end
65
69
 
@@ -143,6 +147,15 @@ class MiddlewareStackTest < Faraday::TestCase
143
147
  assert_match "zomg/i_dont/exist", err.message
144
148
  end
145
149
 
150
+ def test_env_stored_on_middleware_response_has_reference_to_the_response
151
+ env = response = nil
152
+ build_stack Struct.new(:app) {
153
+ define_method(:call) { |e| env, response = e, app.call(e) }
154
+ }
155
+ @conn.get("/")
156
+ assert_same env.response, response.env.response
157
+ end
158
+
146
159
  private
147
160
 
148
161
  # make a stack with test adapter that reflects the order of middleware
@@ -151,11 +164,21 @@ class MiddlewareStackTest < Faraday::TestCase
151
164
  handlers.each { |handler| b.use(*handler) }
152
165
  yield(b) if block_given?
153
166
 
154
- b.adapter :test do |stub|
155
- stub.get '/' do |env|
156
- # echo the "X-Middleware" request header in the body
157
- [200, {}, env[:request_headers]['X-Middleware'].to_s]
158
- end
167
+ @builder.adapter :test, &test_adapter
168
+ end
169
+ end
170
+
171
+ def build_handlers_stack(*handlers)
172
+ @builder.build do |b|
173
+ handlers.each { |handler| b.use(*handler) }
174
+ end
175
+ end
176
+
177
+ def test_adapter
178
+ Proc.new do |stub|
179
+ stub.get '/' do |env|
180
+ # echo the "X-Middleware" request header in the body
181
+ [200, {}, env[:request_headers]['X-Middleware'].to_s]
159
182
  end
160
183
  end
161
184
  end
@@ -171,3 +194,67 @@ class MiddlewareStackTest < Faraday::TestCase
171
194
  component.instance_variable_get('@registered_middleware').delete(key)
172
195
  end
173
196
  end
197
+
198
+ class MiddlewareStackOrderTest < Faraday::TestCase
199
+ def test_adding_response_middleware_after_adapter
200
+ response_after_adapter = lambda do
201
+ Faraday::RackBuilder.new do |b|
202
+ b.adapter :test
203
+ b.response :raise_error
204
+ end
205
+ end
206
+
207
+ assert_output("", expected_middleware_warning, &response_after_adapter)
208
+ end
209
+
210
+ def test_adding_request_middleware_after_adapter
211
+ request_after_adapter = lambda do
212
+ Faraday::RackBuilder.new do |b|
213
+ b.adapter :test
214
+ b.request :multipart
215
+ end
216
+ end
217
+
218
+ assert_output("", expected_middleware_warning, &request_after_adapter)
219
+ end
220
+
221
+ def test_adding_request_middleware_after_adapter_via_use
222
+ use_after_adapter = lambda do
223
+ Faraday::RackBuilder.new do |b|
224
+ b.adapter :test
225
+ b.use Faraday::Request::Multipart
226
+ end
227
+ end
228
+
229
+ assert_output("", expected_middleware_warning, &use_after_adapter)
230
+ end
231
+
232
+ def test_adding_request_middleware_after_adapter_via_insert
233
+ insert_after_adapter = lambda do
234
+ Faraday::RackBuilder.new do |b|
235
+ b.adapter :test
236
+ b.insert(1, Faraday::Request::Multipart)
237
+ end
238
+ end
239
+
240
+ assert_output("", expected_middleware_warning, &insert_after_adapter)
241
+ end
242
+
243
+ def test_adding_request_middleware_before_adapter_via_insert_no_warning
244
+ builder = Faraday::RackBuilder.new do |b|
245
+ b.adapter :test
246
+ end
247
+
248
+ insert_before_adapter = lambda do
249
+ builder.insert(0, Faraday::Request::Multipart)
250
+ end
251
+
252
+ assert_output("", "", &insert_before_adapter)
253
+ end
254
+
255
+ private
256
+
257
+ def expected_middleware_warning
258
+ /Unexpected middleware set after the adapter/
259
+ end
260
+ end
data/test/options_test.rb CHANGED
@@ -1,11 +1,91 @@
1
1
  require File.expand_path('../helper', __FILE__)
2
2
 
3
3
  class OptionsTest < Faraday::TestCase
4
- class SubOptions < Faraday::Options.new(:sub); end
4
+ SubOptions = Class.new(Faraday::Options.new(:sub_a, :sub_b))
5
5
  class ParentOptions < Faraday::Options.new(:a, :b, :c)
6
6
  options :c => SubOptions
7
7
  end
8
8
 
9
+ def test_deep_merge
10
+ sub_opts1 = SubOptions.from(sub_a: 3)
11
+ sub_opts2 = SubOptions.from(sub_b: 4)
12
+ opt1 = ParentOptions.from(a: 1, c: sub_opts1)
13
+ opt2 = ParentOptions.from(b: 2, c: sub_opts2)
14
+
15
+ merged = opt1.merge(opt2)
16
+
17
+ expected_sub_opts = SubOptions.from(sub_a: 3, sub_b: 4)
18
+ assert_equal merged, ParentOptions.from(a: 1, b: 2, c: expected_sub_opts)
19
+ end
20
+
21
+ def test_deep_merge_with_hash
22
+ sub_opts1 = SubOptions.from(sub_a: 3)
23
+ sub_opts2 = { sub_b: 4 }
24
+ opt1 = ParentOptions.from(a: 1, c: sub_opts1)
25
+ opt2 = { b: 2, c: sub_opts2 }
26
+
27
+ merged = opt1.merge(opt2)
28
+
29
+ expected_sub_opts = SubOptions.from(sub_a: 3, sub_b: 4)
30
+ assert_equal merged, ParentOptions.from(a: 1, b: 2, c: expected_sub_opts)
31
+ end
32
+
33
+ def test_deep_merge_with_nil
34
+ sub_opts = SubOptions.new(3, 4)
35
+ options = ParentOptions.new(1, 2, sub_opts)
36
+ assert_equal options.a, 1
37
+ assert_equal options.b, 2
38
+ assert_equal options.c.sub_a, 3
39
+ assert_equal options.c.sub_b, 4
40
+
41
+ options2 = ParentOptions.from(b: 5, c: nil)
42
+
43
+ merged = options.merge(options2)
44
+
45
+ assert_equal merged.b, 5
46
+ assert_equal merged.c, sub_opts
47
+ end
48
+
49
+ def test_deep_merge_with_sub_nil
50
+ options = ParentOptions.from(a: 1)
51
+
52
+ sub_opts = SubOptions.new(3, 4)
53
+ options2 = ParentOptions.from(b: 2, c: sub_opts)
54
+
55
+ assert_equal options.a, 1
56
+ assert_equal options2.b, 2
57
+ assert_equal options2.c.sub_a, 3
58
+ assert_equal options2.c.sub_b, 4
59
+
60
+ merged = options.merge(options2)
61
+
62
+ assert_equal merged.c, sub_opts
63
+ end
64
+
65
+ def test_dup_is_shallow
66
+ sub_opts = SubOptions.from(sub_a: 3)
67
+ opts = ParentOptions.from(b: 1, c: sub_opts)
68
+
69
+ duped = opts.dup
70
+ duped.b = 2
71
+ duped.c.sub_a = 4
72
+
73
+ assert_equal opts.b, 1
74
+ assert_equal opts.c.sub_a, 4
75
+ end
76
+
77
+ def test_deep_dup
78
+ sub_opts = SubOptions.from(sub_a: 3)
79
+ opts = ParentOptions.from(b: 1, c: sub_opts)
80
+
81
+ duped = opts.deep_dup
82
+ duped.b = 2
83
+ duped.c.sub_a = 4
84
+
85
+ assert_equal opts.b, 1
86
+ assert_equal opts.c.sub_a, 3
87
+ end
88
+
9
89
  def test_clear
10
90
  options = SubOptions.new(1)
11
91
  assert !options.empty?
@@ -16,9 +96,9 @@ class OptionsTest < Faraday::TestCase
16
96
  def test_empty
17
97
  options = SubOptions.new
18
98
  assert options.empty?
19
- options.sub = 1
99
+ options.sub_a = 1
20
100
  assert !options.empty?
21
- options.delete(:sub)
101
+ options.delete(:sub_a)
22
102
  assert options.empty?
23
103
  end
24
104
 
@@ -32,13 +112,9 @@ class OptionsTest < Faraday::TestCase
32
112
 
33
113
  def test_key?
34
114
  options = SubOptions.new
35
- assert !options.key?(:sub)
36
- options.sub = 1
37
- if RUBY_VERSION >= '1.9'
38
- assert options.key?(:sub)
39
- else
40
- assert options.key?("sub")
41
- end
115
+ assert !options.key?(:sub_a)
116
+ options.sub_a = 1
117
+ assert options.key?(:sub_a)
42
118
  end
43
119
 
44
120
  def test_each_value
@@ -52,7 +128,7 @@ class OptionsTest < Faraday::TestCase
52
128
  def test_value?
53
129
  options = SubOptions.new
54
130
  assert !options.value?(1)
55
- options.sub = 1
131
+ options.sub_a = 1
56
132
  assert options.value?(1)
57
133
  end
58
134
 
@@ -83,6 +159,11 @@ class OptionsTest < Faraday::TestCase
83
159
  assert_equal 'http', options.scheme
84
160
  end
85
161
 
162
+ def test_proxy_options_from_nil
163
+ options = Faraday::ProxyOptions.from nil
164
+ assert_kind_of Faraday::ProxyOptions, options
165
+ end
166
+
86
167
  def test_proxy_options_hash_access
87
168
  proxy = Faraday::ProxyOptions.from 'http://a%40b:pw%20d@example.org'
88
169
  assert_equal 'a@b', proxy[:user]
@@ -112,7 +193,7 @@ class OptionsTest < Faraday::TestCase
112
193
  assert_equal 1, options.a
113
194
  assert_nil options.b
114
195
  assert_kind_of SubOptions, options.c
115
- assert_equal 1, options.c.sub
196
+ assert_equal 1, options.c.sub_a
116
197
  end
117
198
 
118
199
  def test_from_hash
@@ -123,19 +204,19 @@ class OptionsTest < Faraday::TestCase
123
204
  end
124
205
 
125
206
  def test_from_hash_with_sub_object
126
- options = ParentOptions.from :a => 1, :c => {:sub => 1}
207
+ options = ParentOptions.from :a => 1, :c => {:sub_a => 1}
127
208
  assert_kind_of ParentOptions, options
128
209
  assert_equal 1, options.a
129
210
  assert_nil options.b
130
211
  assert_kind_of SubOptions, options.c
131
- assert_equal 1, options.c.sub
212
+ assert_equal 1, options.c.sub_a
132
213
  end
133
214
 
134
215
  def test_inheritance
135
216
  subclass = Class.new(ParentOptions)
136
- options = subclass.from(:c => {:sub => 'hello'})
217
+ options = subclass.from(:c => {:sub_a => 'hello'})
137
218
  assert_kind_of SubOptions, options.c
138
- assert_equal 'hello', options.c.sub
219
+ assert_equal 'hello', options.c.sub_a
139
220
  end
140
221
 
141
222
  def test_from_deep_hash