faraday 2.9.0 → 2.11.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8daafc733cd0bf7b27c3ec39dcca14da1dd4ad6bf28d72e96c6c7c214d4992e1
4
- data.tar.gz: 8b5ce62606f14fd89a64adbe24099ef53067c98444419bfe58b0b986501dae5d
3
+ metadata.gz: 7ceee5efaef78f039d68da91b621e8ae3723f6663fc11667709845b08358bb53
4
+ data.tar.gz: 430834e5a0cecbc636eecf485eae7061447126e93b5de5f27ad2d7a938a36459
5
5
  SHA512:
6
- metadata.gz: 980d8a35587b2ead1383ac7cd7f8649c193a6d9685c0d69c97f9be4937a18deeef7858d50d2c20649774ac97293d0dc6d4b51049cb40e4f4422132d0c58f372b
7
- data.tar.gz: a02dbd0bd5d2670728f39f2a673b385abda43d7449cb204bff10878e562a179c2de595665096dbc24c4d183990a0417c7386159afb952955806c0ea3321bf5fe
6
+ metadata.gz: 9664749d4913670b04ed973554bf2893fb17f63eb5117a86a36d083615421cbca07212f4797e2869f1ec86905e428f9de89c913c142464bdb6764316ad4edeae
7
+ data.tar.gz: c2d7c4259cfceb8f862e4ea45f8bf7f8f3a7c1896478b882f349539270aac8161fb079b29b0f4fa29b57539a395e9a9d7f62f65ecd76433746373dc0243200b4
data/CHANGELOG.md CHANGED
@@ -517,7 +517,7 @@ Breaking changes:
517
517
  - Drop support for Ruby 1.8
518
518
 
519
519
  Features:
520
- - Include wrapped exception/reponse in ClientErrors
520
+ - Include wrapped exception/response in ClientErrors
521
521
  - Add `response.reason_phrase`
522
522
  - Provide option to selectively skip logging request/response headers
523
523
  - Add regex support for pattern matching in `test` adapter
data/Rakefile CHANGED
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rspec/core/rake_task'
4
+ require 'bundler'
5
+
6
+ Bundler::GemHelper.install_tasks
4
7
 
5
8
  RSpec::Core::RakeTask.new(:spec) do |task|
6
9
  task.ruby_opts = %w[-W]
@@ -26,7 +26,7 @@ module Faraday
26
26
  self.supports_parallel = false
27
27
 
28
28
  def initialize(_app = nil, opts = {}, &block)
29
- @app = ->(env) { env.response }
29
+ @app = lambda(&:response)
30
30
  @connection_options = opts
31
31
  @config_block = block
32
32
  end
@@ -314,15 +314,23 @@ module Faraday
314
314
  #
315
315
  # @yield a block to execute multiple requests.
316
316
  # @return [void]
317
- def in_parallel(manager = nil)
317
+ def in_parallel(manager = nil, &block)
318
318
  @parallel_manager = manager || default_parallel_manager do
319
319
  warn 'Warning: `in_parallel` called but no parallel-capable adapter ' \
320
320
  'on Faraday stack'
321
321
  warn caller[2, 10].join("\n")
322
322
  nil
323
323
  end
324
- yield
325
- @parallel_manager&.run
324
+ return yield unless @parallel_manager
325
+
326
+ if @parallel_manager.respond_to?(:execute)
327
+ # Execute is the new method that is responsible for executing the block.
328
+ @parallel_manager.execute(&block)
329
+ else
330
+ # TODO: Old behaviour, deprecate and remove in 3.0
331
+ yield
332
+ @parallel_manager.run
333
+ end
326
334
  ensure
327
335
  @parallel_manager = nil
328
336
  end
@@ -423,8 +431,8 @@ module Faraday
423
431
  #
424
432
  # @param method [Symbol] HTTP method.
425
433
  # @param url [String, URI, nil] String or URI to access.
426
- # @param body [String, nil] The request body that will eventually be converted to
427
- # a string.
434
+ # @param body [String, Hash, Array, nil] The request body that will eventually be converted to
435
+ # a string; middlewares can be used to support more complex types.
428
436
  # @param headers [Hash, nil] unencoded HTTP header key/value pairs.
429
437
  #
430
438
  # @return [Faraday::Response]
@@ -473,7 +481,8 @@ module Faraday
473
481
  if url && !base.path.end_with?('/')
474
482
  base.path = "#{base.path}/" # ensure trailing slash
475
483
  end
476
- url = url.to_s.gsub(':', '%3A') if URI.parse(url.to_s).opaque
484
+ # Ensure relative url will be parsed correctly (such as `service:search` )
485
+ url = "./#{url}" if url.respond_to?(:start_with?) && !url.start_with?('http://', 'https://', '/', './', '../')
477
486
  uri = url ? base + url : base
478
487
  if params
479
488
  uri.query = params.to_query(params_encoder || options.params_encoder)
data/lib/faraday/error.rb CHANGED
@@ -158,4 +158,8 @@ module Faraday
158
158
  # Raised by middlewares that parse the response, like the JSON response middleware.
159
159
  class ParsingError < Error
160
160
  end
161
+
162
+ # Raised by Faraday::Middleware and subclasses when invalid default_options are used
163
+ class InitializationError < Error
164
+ end
161
165
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'monitor'
4
+
3
5
  module Faraday
4
6
  # Middleware is the basic base class of any Faraday middleware.
5
7
  class Middleware
@@ -7,9 +9,46 @@ module Faraday
7
9
 
8
10
  attr_reader :app, :options
9
11
 
12
+ DEFAULT_OPTIONS = {}.freeze
13
+ LOCK = Mutex.new
14
+
10
15
  def initialize(app = nil, options = {})
11
16
  @app = app
12
- @options = options
17
+ @options = self.class.default_options.merge(options)
18
+ end
19
+
20
+ class << self
21
+ # Faraday::Middleware::default_options= allows user to set default options at the Faraday::Middleware
22
+ # class level.
23
+ #
24
+ # @example Set the Faraday::Response::RaiseError option, `include_request` to `false`
25
+ # my_app/config/initializers/my_faraday_middleware.rb
26
+ #
27
+ # Faraday::Response::RaiseError.default_options = { include_request: false }
28
+ #
29
+ def default_options=(options = {})
30
+ validate_default_options(options)
31
+ LOCK.synchronize do
32
+ @default_options = default_options.merge(options)
33
+ end
34
+ end
35
+
36
+ # default_options attr_reader that initializes class instance variable
37
+ # with the values of any Faraday::Middleware defaults, and merges with
38
+ # subclass defaults
39
+ def default_options
40
+ @default_options ||= DEFAULT_OPTIONS.merge(self::DEFAULT_OPTIONS)
41
+ end
42
+
43
+ private
44
+
45
+ def validate_default_options(options)
46
+ invalid_keys = options.keys.reject { |opt| self::DEFAULT_OPTIONS.key?(opt) }
47
+ return unless invalid_keys.any?
48
+
49
+ raise(Faraday::InitializationError,
50
+ "Invalid options provided. Keys not found in #{self}::DEFAULT_OPTIONS: #{invalid_keys.join(', ')}")
51
+ end
13
52
  end
14
53
 
15
54
  def call(env)
@@ -169,7 +169,7 @@ module Faraday
169
169
  def stream_response(&block)
170
170
  size = 0
171
171
  yielded = false
172
- block_result = block.call do |chunk| # rubocop:disable Performance/RedundantBlockCall
172
+ block_result = block.call do |chunk|
173
173
  if chunk.bytesize.positive? || size.positive?
174
174
  yielded = true
175
175
  size += chunk.bytesize
@@ -46,12 +46,15 @@ module Faraday
46
46
  # #
47
47
  # # @!attribute max_version
48
48
  # # @return [String, Symbol] maximum SSL version (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-max_version-3D)
49
+ # #
50
+ # # @!attribute ciphers
51
+ # # @return [String] cipher list in OpenSSL format (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-ciphers-3D)
49
52
  # class SSLOptions < Options; end
50
53
  SSLOptions = Options.new(:verify, :verify_hostname,
51
54
  :ca_file, :ca_path, :verify_mode,
52
55
  :cert_store, :client_cert, :client_key,
53
56
  :certificate, :private_key, :verify_depth,
54
- :version, :min_version, :max_version) do
57
+ :version, :min_version, :max_version, :ciphers) do
55
58
  # @return [Boolean] true if should verify
56
59
  def verify?
57
60
  verify != false
@@ -60,7 +60,8 @@ module Faraday
60
60
  @decoder_options =
61
61
  if @decoder_options.is_a?(Array) && @decoder_options.size >= 2
62
62
  @decoder_options.slice(0, 2)
63
- elsif @decoder_options.respond_to?(:load)
63
+ elsif @decoder_options&.respond_to?(:load) # rubocop:disable Lint/RedundantSafeNavigation
64
+ # In some versions of Rails, `nil` responds to `load` - hence the safe navigation check above
64
65
  [@decoder_options, :load]
65
66
  else
66
67
  [::JSON, :parse]
@@ -10,6 +10,8 @@ module Faraday
10
10
  ServerErrorStatuses = (500...600)
11
11
  # rubocop:enable Naming/ConstantName
12
12
 
13
+ DEFAULT_OPTIONS = { include_request: true }.freeze
14
+
13
15
  def on_complete(env)
14
16
  case env[:status]
15
17
  when 400
@@ -58,7 +60,7 @@ module Faraday
58
60
 
59
61
  # Include the request data by default. If the middleware was explicitly
60
62
  # configured to _not_ include request data, then omit it.
61
- return response unless options.fetch(:include_request, true)
63
+ return response unless options[:include_request]
62
64
 
63
65
  response.merge(
64
66
  request: {
@@ -62,10 +62,10 @@ module Faraday
62
62
  super(key, val)
63
63
  end
64
64
 
65
- def fetch(key, *args, &block)
65
+ def fetch(key, ...)
66
66
  key = KeyMap[key]
67
67
  key = @names.fetch(key.downcase, key)
68
- super(key, *args, &block)
68
+ super(key, ...)
69
69
  end
70
70
 
71
71
  def delete(key)
@@ -77,6 +77,12 @@ module Faraday
77
77
  super(key)
78
78
  end
79
79
 
80
+ def dig(key, *rest)
81
+ key = KeyMap[key]
82
+ key = @names.fetch(key.downcase, key)
83
+ super(key, *rest)
84
+ end
85
+
80
86
  def include?(key)
81
87
  @names.include? key.downcase
82
88
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Faraday
4
- VERSION = '2.9.0'
4
+ VERSION = '2.11.0'
5
5
  end
@@ -300,14 +300,14 @@ RSpec.describe Faraday::Connection do
300
300
  it 'joins url to base when used relative path' do
301
301
  conn = Faraday.new(url: url)
302
302
  uri = conn.build_exclusive_url('service:search?limit=400')
303
- expect(uri.to_s).to eq('http://service.com/service%3Asearch?limit=400')
303
+ expect(uri.to_s).to eq('http://service.com/service:search?limit=400')
304
304
  end
305
305
 
306
306
  it 'joins url to base when used with path prefix' do
307
307
  conn = Faraday.new(url: url)
308
308
  conn.path_prefix = '/api'
309
309
  uri = conn.build_exclusive_url('service:search?limit=400')
310
- expect(uri.to_s).to eq('http://service.com/api/service%3Asearch?limit=400')
310
+ expect(uri.to_s).to eq('http://service.com/api/service:search?limit=400')
311
311
  end
312
312
  end
313
313
 
@@ -67,4 +67,147 @@ RSpec.describe Faraday::Middleware do
67
67
  end
68
68
  end
69
69
  end
70
+
71
+ describe '::default_options' do
72
+ let(:subclass_no_options) { FaradayMiddlewareSubclasses::SubclassNoOptions }
73
+ let(:subclass_one_option) { FaradayMiddlewareSubclasses::SubclassOneOption }
74
+ let(:subclass_two_options) { FaradayMiddlewareSubclasses::SubclassTwoOptions }
75
+
76
+ def build_conn(resp_middleware)
77
+ Faraday.new do |c|
78
+ c.adapter :test do |stub|
79
+ stub.get('/success') { [200, {}, 'ok'] }
80
+ end
81
+ c.response resp_middleware
82
+ end
83
+ end
84
+
85
+ RSpec.shared_context 'reset @default_options' do
86
+ before(:each) do
87
+ FaradayMiddlewareSubclasses::SubclassNoOptions.instance_variable_set(:@default_options, nil)
88
+ FaradayMiddlewareSubclasses::SubclassOneOption.instance_variable_set(:@default_options, nil)
89
+ FaradayMiddlewareSubclasses::SubclassTwoOptions.instance_variable_set(:@default_options, nil)
90
+ Faraday::Middleware.instance_variable_set(:@default_options, nil)
91
+ end
92
+ end
93
+
94
+ after(:all) do
95
+ FaradayMiddlewareSubclasses::SubclassNoOptions.instance_variable_set(:@default_options, nil)
96
+ FaradayMiddlewareSubclasses::SubclassOneOption.instance_variable_set(:@default_options, nil)
97
+ FaradayMiddlewareSubclasses::SubclassTwoOptions.instance_variable_set(:@default_options, nil)
98
+ Faraday::Middleware.instance_variable_set(:@default_options, nil)
99
+ end
100
+
101
+ context 'with subclass DEFAULT_OPTIONS defined' do
102
+ include_context 'reset @default_options'
103
+
104
+ context 'and without application options configured' do
105
+ let(:resp1) { build_conn(:one_option).get('/success') }
106
+
107
+ it 'has only subclass defaults' do
108
+ expect(Faraday::Middleware.default_options).to eq(Faraday::Middleware::DEFAULT_OPTIONS)
109
+ expect(subclass_no_options.default_options).to eq(subclass_no_options::DEFAULT_OPTIONS)
110
+ expect(subclass_one_option.default_options).to eq(subclass_one_option::DEFAULT_OPTIONS)
111
+ expect(subclass_two_options.default_options).to eq(subclass_two_options::DEFAULT_OPTIONS)
112
+ end
113
+
114
+ it { expect(resp1.body).to eq('ok') }
115
+ end
116
+
117
+ context "and with one application's options changed" do
118
+ let(:resp2) { build_conn(:two_options).get('/success') }
119
+
120
+ before(:each) do
121
+ FaradayMiddlewareSubclasses::SubclassTwoOptions.default_options = { some_option: false }
122
+ end
123
+
124
+ it 'only updates default options of target subclass' do
125
+ expect(Faraday::Middleware.default_options).to eq(Faraday::Middleware::DEFAULT_OPTIONS)
126
+ expect(subclass_no_options.default_options).to eq(subclass_no_options::DEFAULT_OPTIONS)
127
+ expect(subclass_one_option.default_options).to eq(subclass_one_option::DEFAULT_OPTIONS)
128
+ expect(subclass_two_options.default_options).to eq({ some_option: false, some_other_option: false })
129
+ end
130
+
131
+ it { expect(resp2.body).to eq('ok') }
132
+ end
133
+
134
+ context "and with two applications' options changed" do
135
+ let(:resp1) { build_conn(:one_option).get('/success') }
136
+ let(:resp2) { build_conn(:two_options).get('/success') }
137
+
138
+ before(:each) do
139
+ FaradayMiddlewareSubclasses::SubclassOneOption.default_options = { some_other_option: true }
140
+ FaradayMiddlewareSubclasses::SubclassTwoOptions.default_options = { some_option: false }
141
+ end
142
+
143
+ it 'updates subclasses and parent independent of each other' do
144
+ expect(Faraday::Middleware.default_options).to eq(Faraday::Middleware::DEFAULT_OPTIONS)
145
+ expect(subclass_no_options.default_options).to eq(subclass_no_options::DEFAULT_OPTIONS)
146
+ expect(subclass_one_option.default_options).to eq({ some_other_option: true })
147
+ expect(subclass_two_options.default_options).to eq({ some_option: false, some_other_option: false })
148
+ end
149
+
150
+ it { expect(resp1.body).to eq('ok') }
151
+ it { expect(resp2.body).to eq('ok') }
152
+ end
153
+ end
154
+
155
+ context 'with FARADAY::MIDDLEWARE DEFAULT_OPTIONS and with Subclass DEFAULT_OPTIONS' do
156
+ before(:each) do
157
+ stub_const('Faraday::Middleware::DEFAULT_OPTIONS', { its_magic: false })
158
+ end
159
+
160
+ # Must stub Faraday::Middleware::DEFAULT_OPTIONS before resetting default options
161
+ include_context 'reset @default_options'
162
+
163
+ context 'and without application options configured' do
164
+ let(:resp1) { build_conn(:one_option).get('/success') }
165
+
166
+ it 'has only subclass defaults' do
167
+ expect(Faraday::Middleware.default_options).to eq(Faraday::Middleware::DEFAULT_OPTIONS)
168
+ expect(FaradayMiddlewareSubclasses::SubclassNoOptions.default_options).to eq({ its_magic: false })
169
+ expect(FaradayMiddlewareSubclasses::SubclassOneOption.default_options).to eq({ its_magic: false, some_other_option: false })
170
+ expect(FaradayMiddlewareSubclasses::SubclassTwoOptions.default_options).to eq({ its_magic: false, some_option: true, some_other_option: false })
171
+ end
172
+
173
+ it { expect(resp1.body).to eq('ok') }
174
+ end
175
+
176
+ context "and with two applications' options changed" do
177
+ let(:resp1) { build_conn(:one_option).get('/success') }
178
+ let(:resp2) { build_conn(:two_options).get('/success') }
179
+
180
+ before(:each) do
181
+ FaradayMiddlewareSubclasses::SubclassOneOption.default_options = { some_other_option: true }
182
+ FaradayMiddlewareSubclasses::SubclassTwoOptions.default_options = { some_option: false }
183
+ end
184
+
185
+ it 'updates subclasses and parent independent of each other' do
186
+ expect(Faraday::Middleware.default_options).to eq(Faraday::Middleware::DEFAULT_OPTIONS)
187
+ expect(FaradayMiddlewareSubclasses::SubclassNoOptions.default_options).to eq({ its_magic: false })
188
+ expect(FaradayMiddlewareSubclasses::SubclassOneOption.default_options).to eq({ its_magic: false, some_other_option: true })
189
+ expect(FaradayMiddlewareSubclasses::SubclassTwoOptions.default_options).to eq({ its_magic: false, some_option: false, some_other_option: false })
190
+ end
191
+
192
+ it { expect(resp1.body).to eq('ok') }
193
+ it { expect(resp2.body).to eq('ok') }
194
+ end
195
+ end
196
+
197
+ describe 'default_options input validation' do
198
+ include_context 'reset @default_options'
199
+
200
+ it 'raises error if Faraday::Middleware option does not exist' do
201
+ expect { Faraday::Middleware.default_options = { something_special: true } }.to raise_error(Faraday::InitializationError) do |e|
202
+ expect(e.message).to eq('Invalid options provided. Keys not found in Faraday::Middleware::DEFAULT_OPTIONS: something_special')
203
+ end
204
+ end
205
+
206
+ it 'raises error if subclass option does not exist' do
207
+ expect { subclass_one_option.default_options = { this_is_a_typo: true } }.to raise_error(Faraday::InitializationError) do |e|
208
+ expect(e.message).to eq('Invalid options provided. Keys not found in FaradayMiddlewareSubclasses::SubclassOneOption::DEFAULT_OPTIONS: this_is_a_typo')
209
+ end
210
+ end
211
+ end
212
+ end
70
213
  end
@@ -62,7 +62,8 @@ RSpec.describe Faraday::NestedParamsEncoder do
62
62
  it 'encodes rack compat' do
63
63
  params = { a: [{ one: '1', two: '2' }, '3', ''] }
64
64
  result = Faraday::Utils.unescape(Faraday::NestedParamsEncoder.encode(params)).split('&')
65
- expected = Rack::Utils.build_nested_query(params).split('&')
65
+ escaped = Rack::Utils.build_nested_query(params)
66
+ expected = Rack::Utils.unescape(escaped).split('&')
66
67
  expect(result).to match_array(expected)
67
68
  end
68
69
 
@@ -184,6 +184,23 @@ RSpec.describe Faraday::Response::Json, type: :response do
184
184
  response = process(body)
185
185
  expect(response.body).to eq(result)
186
186
  end
187
+
188
+ it 'passes relevant options to JSON parse even when nil responds to :load' do
189
+ original_allow_message_expectations_on_nil = RSpec::Mocks.configuration.allow_message_expectations_on_nil
190
+ RSpec::Mocks.configuration.allow_message_expectations_on_nil = true
191
+ allow(nil).to receive(:respond_to?)
192
+ .with(:load)
193
+ .and_return(true)
194
+
195
+ expect(JSON).to receive(:parse)
196
+ .with(body, { symbolize_names: true })
197
+ .and_return(result)
198
+
199
+ response = process(body)
200
+ expect(response.body).to eq(result)
201
+ ensure
202
+ RSpec::Mocks.configuration.allow_message_expectations_on_nil = original_allow_message_expectations_on_nil
203
+ end
187
204
  end
188
205
  end
189
206
  end
@@ -194,16 +194,60 @@ RSpec.describe Faraday::Response::RaiseError do
194
194
  end
195
195
  end
196
196
 
197
- context 'when the include_request option is set to false' do
198
- let(:middleware_options) { { include_request: false } }
199
-
200
- it 'does not include request info in the exception' do
201
- expect { perform_request }.to raise_error(Faraday::BadRequestError) do |ex|
202
- expect(ex.response.keys).to contain_exactly(
203
- :status,
204
- :headers,
205
- :body
206
- )
197
+ describe 'DEFAULT_OPTION: include_request' do
198
+ before(:each) do
199
+ Faraday::Response::RaiseError.instance_variable_set(:@default_options, nil)
200
+ Faraday::Middleware.instance_variable_set(:@default_options, nil)
201
+ end
202
+
203
+ after(:all) do
204
+ Faraday::Response::RaiseError.instance_variable_set(:@default_options, nil)
205
+ Faraday::Middleware.instance_variable_set(:@default_options, nil)
206
+ end
207
+
208
+ context 'when RaiseError DEFAULT_OPTION (include_request: true) is used' do
209
+ it 'includes request info in the exception' do
210
+ expect { perform_request }.to raise_error(Faraday::BadRequestError) do |ex|
211
+ expect(ex.response.keys).to contain_exactly(
212
+ :status,
213
+ :headers,
214
+ :body,
215
+ :request
216
+ )
217
+ end
218
+ end
219
+ end
220
+
221
+ context 'when application sets default_options `include_request: false`' do
222
+ before(:each) do
223
+ Faraday::Response::RaiseError.default_options = { include_request: false }
224
+ end
225
+
226
+ context 'and when include_request option is omitted' do
227
+ it 'does not include request info in the exception' do
228
+ expect { perform_request }.to raise_error(Faraday::BadRequestError) do |ex|
229
+ expect(ex.response.keys).to contain_exactly(
230
+ :status,
231
+ :headers,
232
+ :body
233
+ )
234
+ end
235
+ end
236
+ end
237
+
238
+ context 'and when include_request option is explicitly set for instance' do
239
+ let(:middleware_options) { { include_request: true } }
240
+
241
+ it 'includes request info in the exception' do
242
+ expect { perform_request }.to raise_error(Faraday::BadRequestError) do |ex|
243
+ expect(ex.response.keys).to contain_exactly(
244
+ :status,
245
+ :headers,
246
+ :body,
247
+ :request
248
+ )
249
+ end
250
+ end
207
251
  end
208
252
  end
209
253
  end
@@ -56,6 +56,15 @@ RSpec.describe Faraday::Utils::Headers do
56
56
  it { expect(subject.delete('content-type')).to be_nil }
57
57
  end
58
58
 
59
+ describe '#dig' do
60
+ before { subject['Content-Type'] = 'application/json' }
61
+
62
+ it { expect(subject&.dig('Content-Type')).to eq('application/json') }
63
+ it { expect(subject&.dig('CONTENT-TYPE')).to eq('application/json') }
64
+ it { expect(subject&.dig(:content_type)).to eq('application/json') }
65
+ it { expect(subject&.dig('invalid')).to be_nil }
66
+ end
67
+
59
68
  describe '#parse' do
60
69
  context 'when response headers leave http status line out' do
61
70
  let(:headers) { "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n" }
@@ -103,7 +103,8 @@ RSpec.describe Faraday::Utils do
103
103
  version: '2',
104
104
  min_version: nil,
105
105
  max_version: nil,
106
- verify_hostname: nil
106
+ verify_hostname: nil,
107
+ ciphers: nil
107
108
  }
108
109
  end
109
110
 
data/spec/faraday_spec.rb CHANGED
@@ -19,7 +19,9 @@ RSpec.describe Faraday do
19
19
 
20
20
  it 'uses method_missing on Faraday if there is no proxyable method' do
21
21
  expected_message =
22
- if RUBY_VERSION >= '3.3'
22
+ if RUBY_VERSION >= '3.4'
23
+ "undefined method 'this_method_does_not_exist' for module Faraday"
24
+ elsif RUBY_VERSION >= '3.3'
23
25
  "undefined method `this_method_does_not_exist' for module Faraday"
24
26
  else
25
27
  "undefined method `this_method_does_not_exist' for Faraday:Module"
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FaradayMiddlewareSubclasses
4
+ class SubclassNoOptions < Faraday::Middleware
5
+ end
6
+
7
+ class SubclassOneOption < Faraday::Middleware
8
+ DEFAULT_OPTIONS = { some_other_option: false }.freeze
9
+ end
10
+
11
+ class SubclassTwoOptions < Faraday::Middleware
12
+ DEFAULT_OPTIONS = { some_option: true, some_other_option: false }.freeze
13
+ end
14
+ end
15
+
16
+ Faraday::Response.register_middleware(no_options: FaradayMiddlewareSubclasses::SubclassNoOptions)
17
+ Faraday::Response.register_middleware(one_option: FaradayMiddlewareSubclasses::SubclassOneOption)
18
+ Faraday::Response.register_middleware(two_options: FaradayMiddlewareSubclasses::SubclassTwoOptions)
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: 2.9.0
4
+ version: 2.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "@technoweenie"
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-01-09 00:00:00.000000000 Z
13
+ date: 2024-08-26 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: faraday-net_http
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '2.0'
22
22
  - - "<"
23
23
  - !ruby/object:Gem::Version
24
- version: '3.2'
24
+ version: '3.4'
25
25
  type: :runtime
26
26
  prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
@@ -31,7 +31,21 @@ dependencies:
31
31
  version: '2.0'
32
32
  - - "<"
33
33
  - !ruby/object:Gem::Version
34
- version: '3.2'
34
+ version: '3.4'
35
+ - !ruby/object:Gem::Dependency
36
+ name: logger
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ type: :runtime
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
35
49
  description:
36
50
  email: technoweenie@gmail.com
37
51
  executables: []
@@ -107,6 +121,7 @@ files:
107
121
  - spec/spec_helper.rb
108
122
  - spec/support/disabling_stub.rb
109
123
  - spec/support/fake_safe_buffer.rb
124
+ - spec/support/faraday_middleware_subclasses.rb
110
125
  - spec/support/helper_methods.rb
111
126
  - spec/support/shared_examples/adapter.rb
112
127
  - spec/support/shared_examples/params_encoder.rb
@@ -117,9 +132,10 @@ licenses:
117
132
  - MIT
118
133
  metadata:
119
134
  homepage_uri: https://lostisland.github.io/faraday
120
- changelog_uri: https://github.com/lostisland/faraday/releases/tag/v2.9.0
135
+ changelog_uri: https://github.com/lostisland/faraday/releases/tag/v2.11.0
121
136
  source_code_uri: https://github.com/lostisland/faraday
122
137
  bug_tracker_uri: https://github.com/lostisland/faraday/issues
138
+ rubygems_mfa_required: 'true'
123
139
  post_install_message:
124
140
  rdoc_options: []
125
141
  require_paths:
@@ -136,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
152
  - !ruby/object:Gem::Version
137
153
  version: '0'
138
154
  requirements: []
139
- rubygems_version: 3.5.3
155
+ rubygems_version: 3.5.11
140
156
  signing_key:
141
157
  specification_version: 4
142
158
  summary: HTTP/REST API client library.