faraday 1.9.3 → 1.10.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54fc3007a99cab5f45291408bfb7e2b1f6d243abcae060f5d485731328acb031
4
- data.tar.gz: 0fc0eb9ab470bca83b7b6fbc8cafcd9d141dd97eda575f63cf4b2bc6dcb36a65
3
+ metadata.gz: 5a35b8ef069416d74f46cbe1f9b14b9d28e8b141bed4143d2c97ac137b766f18
4
+ data.tar.gz: cdbb3768e4aa6d316e2216ec7fdf2a93b5141abe83dd82b3ffa522002b01523c
5
5
  SHA512:
6
- metadata.gz: ed9fee068b4cbbe13bacfa7eb01d02b919c0ffd72345a4449127f9ad11c7a7e585fa891c8d7791861fa91c8ebe47b9d7e78f760680eaf856db3c029c5f5cc1e0
7
- data.tar.gz: 47d4550ed834bdd5938312aafd9ea9ca4be061a12cd564fa83d08e7c67a44445a8870d12ef0030b6d9d84796813e97ff7ca859722ca786e449cfc25c66ebdb23
6
+ metadata.gz: 743727fca5013eb1bd1f005c334d171fc59a5cb56687395b3d14a48911ee4b7fef5da00e64ac6dbe15b75cc76edcb26d400b4d748e9676d9cdb12e8d2d8ee7b7
7
+ data.tar.gz: 203527c8adc2828334b74e97a33041ed9127548b91905d15331ff627c5f20d679c3d2ccd0b3102c0de35e011c5f15f2bac50b8aa4eccaeafaf1551611ca020e1
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'faraday/deprecate'
4
+
3
5
  module Faraday
4
6
  # Connection objects manage the default properties and the middleware
5
7
  # stack for fulfilling an HTTP request.
@@ -297,14 +299,12 @@ module Faraday
297
299
  #
298
300
  # @return [void]
299
301
  def basic_auth(login, pass)
300
- warn <<~TEXT
301
- WARNING: `Faraday::Connection#basic_auth` is deprecated; it will be removed in version 2.0.
302
- While initializing your connection, use `#request(:basic_auth, ...)` instead.
303
- See https://lostisland.github.io/faraday/middleware/authentication for more usage info.
304
- TEXT
305
302
  set_authorization_header(:basic_auth, login, pass)
306
303
  end
307
304
 
305
+ extend Faraday::Deprecate
306
+ deprecate :basic_auth, '#request(:basic_auth, ...)', '2.0'
307
+
308
308
  # Sets up the Authorization header with the given token.
309
309
  #
310
310
  # @param token [String]
@@ -319,14 +319,14 @@ module Faraday
319
319
  #
320
320
  # @return [void]
321
321
  def token_auth(token, options = nil)
322
- warn <<~TEXT
323
- WARNING: `Faraday::Connection#token_auth` is deprecated; it will be removed in version 2.0.
324
- While initializing your connection, use `#request(:token_auth, ...)` instead.
325
- See https://lostisland.github.io/faraday/middleware/authentication for more usage info.
326
- TEXT
327
322
  set_authorization_header(:token_auth, token, options)
328
323
  end
329
324
 
325
+ deprecate :token_auth,
326
+ '#request(:token_auth, ...)',
327
+ '2.0',
328
+ 'See https://lostisland.github.io/faraday/middleware/authentication for more usage info.'
329
+
330
330
  # Sets up a custom Authorization header.
331
331
  #
332
332
  # @param type [String] authorization type
@@ -346,14 +346,14 @@ module Faraday
346
346
  #
347
347
  # @return [void]
348
348
  def authorization(type, token)
349
- warn <<~TEXT
350
- WARNING: `Faraday::Connection#authorization` is deprecated; it will be removed in version 2.0.
351
- While initializing your connection, use `#request(:authorization, ...)` instead.
352
- See https://lostisland.github.io/faraday/middleware/authentication for more usage info.
353
- TEXT
354
349
  set_authorization_header(:authorization, type, token)
355
350
  end
356
351
 
352
+ deprecate :authorization,
353
+ '#request(:authorization, ...)',
354
+ '2.0',
355
+ 'See https://lostisland.github.io/faraday/middleware/authentication for more usage info.'
356
+
357
357
  # Check if the adapter is parallel-capable.
358
358
  #
359
359
  # @yield if the adapter isn't parallel-capable, or if no adapter is set yet.
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'ruby2_keywords'
4
+
3
5
  module Faraday
4
6
  # DependencyLoader helps Faraday adapters and middleware load dependencies.
5
7
  module DependencyLoader
@@ -13,7 +15,7 @@ module Faraday
13
15
  self.load_error = e
14
16
  end
15
17
 
16
- def new(*)
18
+ ruby2_keywords def new(*)
17
19
  unless loaded?
18
20
  raise "missing dependency for #{self}: #{load_error.message}"
19
21
  end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ # @param new_klass [Class] new Klass to use
5
+ #
6
+ # @return [Class] A modified version of new_klass that warns on
7
+ # usage about deprecation.
8
+ # @see Faraday::Deprecate
9
+ module DeprecatedClass
10
+ def self.proxy_class(origclass, ver = '1.0')
11
+ proxy = Class.new(origclass) do
12
+ const_set('ORIG_CLASS', origclass)
13
+
14
+ class << self
15
+ extend Faraday::Deprecate
16
+
17
+ def ===(other)
18
+ (superclass == const_get('ORIG_CLASS') && other.is_a?(superclass)) || super
19
+ end
20
+ end
21
+ end
22
+ proxy.singleton_class.send(:deprecate, :new, "#{origclass}.new", ver)
23
+ proxy.singleton_class.send(:deprecate, :inherited, origclass.name, ver)
24
+ proxy
25
+ end
26
+ end
27
+
28
+ # Deprecation using semver instead of date, based on Gem::Deprecate
29
+ # Provides a single method +deprecate+ to be used to declare when
30
+ # something is going away.
31
+ #
32
+ # class Legacy
33
+ # def self.klass_method
34
+ # # ...
35
+ # end
36
+ #
37
+ # def instance_method
38
+ # # ...
39
+ # end
40
+ #
41
+ # extend Faraday::Deprecate
42
+ # deprecate :instance_method, "X.z", '1.0'
43
+ #
44
+ # class << self
45
+ # extend Faraday::Deprecate
46
+ # deprecate :klass_method, :none, '1.0'
47
+ # end
48
+ # end
49
+ module Deprecate
50
+ def self.skip # :nodoc:
51
+ @skip ||= begin
52
+ case ENV['FARADAY_DEPRECATE'].to_s.downcase
53
+ when '1', 'warn' then :warn
54
+ else :skip
55
+ end
56
+ end
57
+ @skip == :skip
58
+ end
59
+
60
+ def self.skip=(value) # :nodoc:
61
+ @skip = value ? :skip : :warn
62
+ end
63
+
64
+ # Temporarily turn off warnings. Intended for tests only.
65
+ def skip_during
66
+ original = Faraday::Deprecate.skip
67
+ Faraday::Deprecate.skip = true
68
+ yield
69
+ ensure
70
+ Faraday::Deprecate.skip = original
71
+ end
72
+
73
+ # Simple deprecation method that deprecates +name+ by wrapping it up
74
+ # in a dummy method. It warns on each call to the dummy method
75
+ # telling the user of +repl+ (unless +repl+ is :none) and the
76
+ # semver that it is planned to go away.
77
+ # @param name [Symbol] the method symbol to deprecate
78
+ # @param repl [#to_s, :none] the replacement to use, when `:none` it will
79
+ # alert the user that no replacement is present.
80
+ # @param ver [String] the semver the method will be removed.
81
+ def deprecate(name, repl, ver, custom_message = nil)
82
+ class_eval do
83
+ gem_ver = Gem::Version.new(ver)
84
+ old = "_deprecated_#{name}"
85
+ alias_method old, name
86
+ define_method name do |*args, &block|
87
+ mod = is_a? Module
88
+ target = mod ? "#{self}." : "#{self.class}#"
89
+ target_message = if name == :inherited
90
+ "Inheriting #{self}"
91
+ else
92
+ "#{target}#{name}"
93
+ end
94
+
95
+ msg = [
96
+ "NOTE: #{target_message} is deprecated",
97
+ repl == :none ? ' with no replacement' : "; use #{repl} instead. ",
98
+ "It will be removed in or after version #{gem_ver} ",
99
+ custom_message,
100
+ "\n#{target}#{name} called from #{Gem.location_of_caller.join(':')}"
101
+ ]
102
+ warn "#{msg.join}." unless Faraday::Deprecate.skip
103
+ send old, *args, &block
104
+ end
105
+ end
106
+ end
107
+
108
+ module_function :deprecate, :skip_during
109
+ end
110
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Faraday
6
+ class Request
7
+ # Request middleware that encodes the body as JSON.
8
+ #
9
+ # Processes only requests with matching Content-type or those without a type.
10
+ # If a request doesn't have a type but has a body, it sets the Content-type
11
+ # to JSON MIME-type.
12
+ #
13
+ # Doesn't try to encode bodies that already are in string form.
14
+ class Json < Middleware
15
+ MIME_TYPE = 'application/json'
16
+ MIME_TYPE_REGEX = %r{^application/(vnd\..+\+)?json$}.freeze
17
+
18
+ def on_request(env)
19
+ match_content_type(env) do |data|
20
+ env[:body] = encode(data)
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def encode(data)
27
+ ::JSON.generate(data)
28
+ end
29
+
30
+ def match_content_type(env)
31
+ return unless process_request?(env)
32
+
33
+ env[:request_headers][CONTENT_TYPE] ||= MIME_TYPE
34
+ yield env[:body] unless env[:body].respond_to?(:to_str)
35
+ end
36
+
37
+ def process_request?(env)
38
+ type = request_type(env)
39
+ body?(env) && (type.empty? || type.match?(MIME_TYPE_REGEX))
40
+ end
41
+
42
+ def body?(env)
43
+ (body = env[:body]) && !(body.respond_to?(:to_str) && body.empty?)
44
+ end
45
+
46
+ def request_type(env)
47
+ type = env[:request_headers][CONTENT_TYPE].to_s
48
+ type = type.split(';', 2).first if type.index(';')
49
+ type
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ Faraday::Request.register_middleware(json: Faraday::Request::Json)
@@ -44,7 +44,8 @@ module Faraday
44
44
  :TokenAuthentication,
45
45
  'token_authentication'
46
46
  ],
47
- instrumentation: [:Instrumentation, 'instrumentation']
47
+ instrumentation: [:Instrumentation, 'instrumentation'],
48
+ json: [:Json, 'json']
48
49
 
49
50
  # @param request_method [String]
50
51
  # @yield [request] for block customization, if block given
@@ -57,13 +58,12 @@ module Faraday
57
58
  end
58
59
 
59
60
  def method
60
- warn <<~TEXT
61
- WARNING: `Faraday::Request##{__method__}` is deprecated; use `#http_method` instead. It will be removed in or after version 2.0.
62
- `Faraday::Request##{__method__}` called from #{caller_locations(1..1).first}
63
- TEXT
64
61
  http_method
65
62
  end
66
63
 
64
+ extend Faraday::Deprecate
65
+ deprecate :method, :http_method, '2.0'
66
+
67
67
  # Replace params, preserving the existing hash type.
68
68
  #
69
69
  # @param hash [Hash] new params
@@ -138,11 +138,11 @@ module Faraday
138
138
  # @param serialised [Hash] the serialised object.
139
139
  def marshal_load(serialised)
140
140
  self.http_method = serialised[:http_method]
141
- self.body = serialised[:body]
142
- self.headers = serialised[:headers]
143
- self.path = serialised[:path]
144
- self.params = serialised[:params]
145
- self.options = serialised[:options]
141
+ self.body = serialised[:body]
142
+ self.headers = serialised[:headers]
143
+ self.path = serialised[:path]
144
+ self.params = serialised[:params]
145
+ self.options = serialised[:options]
146
146
  end
147
147
 
148
148
  # @return [Env] the Env for this Request
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Faraday
6
+ class Response
7
+ # Parse response bodies as JSON.
8
+ class Json < Middleware
9
+ def initialize(app = nil, options = {})
10
+ super(app)
11
+ @parser_options = options[:parser_options]
12
+ @content_types = Array(options[:content_type] || /\bjson$/)
13
+ @preserve_raw = options[:preserve_raw]
14
+ end
15
+
16
+ def on_complete(env)
17
+ process_response(env) if parse_response?(env)
18
+ end
19
+
20
+ private
21
+
22
+ def process_response(env)
23
+ env[:raw_body] = env[:body] if @preserve_raw
24
+ env[:body] = parse(env[:body])
25
+ rescue StandardError, SyntaxError => e
26
+ raise Faraday::ParsingError.new(e, env[:response])
27
+ end
28
+
29
+ def parse(body)
30
+ ::JSON.parse(body, @parser_options || {}) unless body.strip.empty?
31
+ end
32
+
33
+ def parse_response?(env)
34
+ process_response_type?(env) &&
35
+ env[:body].respond_to?(:to_str)
36
+ end
37
+
38
+ def process_response_type?(env)
39
+ type = response_type(env)
40
+ @content_types.empty? || @content_types.any? do |pattern|
41
+ pattern.is_a?(Regexp) ? type.match?(pattern) : type == pattern
42
+ end
43
+ end
44
+
45
+ def response_type(env)
46
+ type = env[:response_headers][CONTENT_TYPE].to_s
47
+ type = type.split(';', 2).first if type.index(';')
48
+ type
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ Faraday::Response.register_middleware(json: Faraday::Response::Json)
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'forwardable'
4
+ require 'logger'
4
5
  require 'faraday/logging/formatter'
5
6
 
6
7
  module Faraday
@@ -11,10 +12,7 @@ module Faraday
11
12
  class Logger < Middleware
12
13
  def initialize(app, logger = nil, options = {})
13
14
  super(app)
14
- logger ||= begin
15
- require 'logger'
16
- ::Logger.new($stdout)
17
- end
15
+ logger ||= ::Logger.new($stdout)
18
16
  formatter_class = options.delete(:formatter) || Logging::Formatter
19
17
  @formatter = formatter_class.new(logger: logger, options: options)
20
18
  yield @formatter if block_given?
@@ -22,7 +22,8 @@ module Faraday
22
22
 
23
23
  register_middleware File.expand_path('response', __dir__),
24
24
  raise_error: [:RaiseError, 'raise_error'],
25
- logger: [:Logger, 'logger']
25
+ logger: [:Logger, 'logger'],
26
+ json: [:Json, 'json']
26
27
 
27
28
  def initialize(env = nil)
28
29
  @env = Env.from(env) if env
@@ -42,6 +43,7 @@ module Faraday
42
43
  def headers
43
44
  finished? ? env.response_headers : {}
44
45
  end
46
+
45
47
  def_delegator :headers, :[]
46
48
 
47
49
  def body
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Faraday
4
- VERSION = '1.9.3'
4
+ VERSION = '1.10.3'
5
5
  end
data/lib/faraday.rb CHANGED
@@ -57,6 +57,8 @@ require 'faraday/rack'
57
57
  # conn.get '/'
58
58
  #
59
59
  module Faraday
60
+ CONTENT_TYPE = 'Content-Type'
61
+
60
62
  class << self
61
63
  # The root path that Faraday is being loaded from.
62
64
  #
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Faraday::DeprecatedClass do
4
+ class SampleClass < StandardError
5
+ attr_accessor :foo
6
+
7
+ def initialize(foo = nil)
8
+ @foo = foo || :foo
9
+ end
10
+ end
11
+
12
+ SampleDeprecatedClass = Faraday::DeprecatedClass.proxy_class(SampleClass)
13
+
14
+ it 'does not raise error for deprecated classes but prints an error message' do
15
+ error_message, foobar = with_warn_squelching { SampleDeprecatedClass.new(:foo_bar) }
16
+ expect(foobar).to be_a(SampleClass)
17
+ expect(foobar.foo).to eq(:foo_bar)
18
+ expect(error_message).to match(
19
+ Regexp.new(
20
+ 'NOTE: SampleDeprecatedClass.new is deprecated; '\
21
+ 'use SampleClass.new instead. It will be removed in or after version 1.0'
22
+ )
23
+ )
24
+ end
25
+
26
+ it 'does not raise an error for inherited error-namespaced classes but prints an error message' do
27
+ error_message, = with_warn_squelching { Class.new(SampleDeprecatedClass) }
28
+
29
+ expect(error_message).to match(
30
+ Regexp.new(
31
+ 'NOTE: Inheriting SampleDeprecatedClass is deprecated; '\
32
+ 'use SampleClass instead. It will be removed in or after version 1.0'
33
+ )
34
+ )
35
+ end
36
+
37
+ it 'allows backward-compatible class to be subclassed' do
38
+ expect do
39
+ with_warn_squelching { Class.new(SampleDeprecatedClass) }
40
+ end.not_to raise_error
41
+ end
42
+
43
+ it 'allows rescuing of a current error with a deprecated error' do
44
+ expect { raise SampleClass, nil }.to raise_error(SampleDeprecatedClass)
45
+ end
46
+
47
+ it 'allows rescuing of a current error with a current error' do
48
+ expect { raise SampleClass, nil }.to raise_error(SampleClass)
49
+ end
50
+
51
+ it 'allows rescuing of a deprecated error with a deprecated error' do
52
+ expect { raise SampleDeprecatedClass, nil }.to raise_error(SampleDeprecatedClass)
53
+ end
54
+
55
+ it 'allows rescuing of a deprecated error with a current error' do
56
+ expect { raise SampleDeprecatedClass, nil }.to raise_error(SampleClass)
57
+ end
58
+
59
+ describe 'match behavior' do
60
+ class SampleDeprecatedClassA < SampleDeprecatedClass; end
61
+ class SampleDeprecatedClassB < SampleDeprecatedClass; end
62
+
63
+ class SampleDeprecatedClassAX < SampleDeprecatedClassA; end
64
+
65
+ class SampleClassA < SampleClass; end
66
+
67
+ describe 'undeprecated class' do
68
+ it 'is === to instance of deprecated class' do
69
+ expect(SampleDeprecatedClass.new.is_a?(SampleClass)).to be true
70
+ end
71
+
72
+ it 'is === to instance of subclass of deprecated class' do
73
+ expect(SampleDeprecatedClassA.new.is_a?(SampleClass)).to be true
74
+ end
75
+
76
+ it 'is === to instance of subclass of subclass of deprecated class' do
77
+ expect(SampleDeprecatedClassAX.new.is_a?(SampleClass)).to be true
78
+ end
79
+ end
80
+
81
+ describe 'subclass of undeprecated class' do
82
+ it 'is not === to instance of undeprecated class' do
83
+ expect(SampleClass.new.is_a?(SampleClassA)).to be false
84
+ end
85
+
86
+ it 'is not === to instance of deprecated class' do
87
+ expect(SampleDeprecatedClass.new.is_a?(SampleClassA)).to be false
88
+ end
89
+ end
90
+
91
+ describe 'deprecated class' do
92
+ it 'is === to instance of undeprecated class' do
93
+ expect(SampleDeprecatedClass.new.is_a?(SampleClass)).to be true
94
+ end
95
+
96
+ it 'is === to instance of subclass of undeprecated class' do
97
+ expect(SampleClassA.superclass == SampleDeprecatedClass.superclass).to be true
98
+ end
99
+
100
+ it 'is === to instance of subclass of deprecated class' do
101
+ expect(SampleDeprecatedClassA.new.is_a?(SampleDeprecatedClass)).to be true
102
+ end
103
+
104
+ it 'is === to instance of subclass of subclass of deprecated class' do
105
+ expect(SampleDeprecatedClassAX.new.is_a?(SampleDeprecatedClass)).to be true
106
+ end
107
+ end
108
+
109
+ describe 'subclass of deprecated class' do
110
+ it 'is not === to instance of subclass of undeprecated class' do
111
+ expect(SampleClass.new.is_a?(SampleDeprecatedClassA)).to be false
112
+ end
113
+
114
+ it 'is not === to instance of another subclass of deprecated class' do
115
+ expect(SampleDeprecatedClassB.new.is_a?(SampleDeprecatedClassA)).to be false
116
+ end
117
+
118
+ it 'is === to instance of its subclass' do
119
+ expect(SampleDeprecatedClassAX.new.is_a?(SampleDeprecatedClassA)).to be true
120
+ end
121
+
122
+ it 'is === to instance of deprecated class' do
123
+ expect(SampleDeprecatedClassB.new.is_a?(SampleDeprecatedClass)).to be true
124
+ end
125
+ end
126
+
127
+ describe 'subclass of subclass of deprecated class' do
128
+ it 'is not === to instance of subclass of another subclass of deprecated class' do
129
+ expect(SampleDeprecatedClassB.new.is_a?(SampleDeprecatedClassAX)).to be false
130
+ end
131
+
132
+ it 'is not === to instance of its superclass' do
133
+ expect(SampleDeprecatedClass.new.is_a?(SampleDeprecatedClassA)).to be false
134
+ end
135
+ end
136
+ end
137
+
138
+ def with_warn_squelching
139
+ stderr_catcher = StringIO.new
140
+ original_stderr = $stderr
141
+ $stderr = stderr_catcher
142
+ result = yield if block_given?
143
+ [stderr_catcher.tap(&:rewind).string, result]
144
+ ensure
145
+ $stderr = original_stderr
146
+ end
147
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Faraday::Request::Json do
4
+ let(:middleware) { described_class.new(->(env) { Faraday::Response.new(env) }) }
5
+
6
+ def process(body, content_type = nil)
7
+ env = { body: body, request_headers: Faraday::Utils::Headers.new }
8
+ env[:request_headers]['content-type'] = content_type if content_type
9
+ middleware.call(Faraday::Env.from(env)).env
10
+ end
11
+
12
+ def result_body
13
+ result[:body]
14
+ end
15
+
16
+ def result_type
17
+ result[:request_headers]['content-type']
18
+ end
19
+
20
+ context 'no body' do
21
+ let(:result) { process(nil) }
22
+
23
+ it "doesn't change body" do
24
+ expect(result_body).to be_nil
25
+ end
26
+
27
+ it "doesn't add content type" do
28
+ expect(result_type).to be_nil
29
+ end
30
+ end
31
+
32
+ context 'empty body' do
33
+ let(:result) { process('') }
34
+
35
+ it "doesn't change body" do
36
+ expect(result_body).to be_empty
37
+ end
38
+
39
+ it "doesn't add content type" do
40
+ expect(result_type).to be_nil
41
+ end
42
+ end
43
+
44
+ context 'string body' do
45
+ let(:result) { process('{"a":1}') }
46
+
47
+ it "doesn't change body" do
48
+ expect(result_body).to eq('{"a":1}')
49
+ end
50
+
51
+ it 'adds content type' do
52
+ expect(result_type).to eq('application/json')
53
+ end
54
+ end
55
+
56
+ context 'object body' do
57
+ let(:result) { process(a: 1) }
58
+
59
+ it 'encodes body' do
60
+ expect(result_body).to eq('{"a":1}')
61
+ end
62
+
63
+ it 'adds content type' do
64
+ expect(result_type).to eq('application/json')
65
+ end
66
+ end
67
+
68
+ context 'empty object body' do
69
+ let(:result) { process({}) }
70
+
71
+ it 'encodes body' do
72
+ expect(result_body).to eq('{}')
73
+ end
74
+ end
75
+
76
+ context 'object body with json type' do
77
+ let(:result) { process({ a: 1 }, 'application/json; charset=utf-8') }
78
+
79
+ it 'encodes body' do
80
+ expect(result_body).to eq('{"a":1}')
81
+ end
82
+
83
+ it "doesn't change content type" do
84
+ expect(result_type).to eq('application/json; charset=utf-8')
85
+ end
86
+ end
87
+
88
+ context 'object body with vendor json type' do
89
+ let(:result) { process({ a: 1 }, 'application/vnd.myapp.v1+json; charset=utf-8') }
90
+
91
+ it 'encodes body' do
92
+ expect(result_body).to eq('{"a":1}')
93
+ end
94
+
95
+ it "doesn't change content type" do
96
+ expect(result_type).to eq('application/vnd.myapp.v1+json; charset=utf-8')
97
+ end
98
+ end
99
+
100
+ context 'object body with incompatible type' do
101
+ let(:result) { process({ a: 1 }, 'application/xml; charset=utf-8') }
102
+
103
+ it "doesn't change body" do
104
+ expect(result_body).to eq(a: 1)
105
+ end
106
+
107
+ it "doesn't change content type" do
108
+ expect(result_type).to eq('application/xml; charset=utf-8')
109
+ end
110
+ end
111
+ end
@@ -25,7 +25,7 @@ RSpec.describe Faraday::Request do
25
25
  describe 'deprecate method for HTTP method' do
26
26
  let(:http_method) { :post }
27
27
  let(:expected_warning) do
28
- %r{WARNING: `Faraday::Request#method` is deprecated; use `#http_method` instead. It will be removed in or after version 2.0.\n`Faraday::Request#method` called from .+/spec/faraday/request_spec.rb:\d+.}
28
+ %r{NOTE: Faraday::Request#method is deprecated; use http_method instead\. It will be removed in or after version 2.0 \nFaraday::Request#method called from .+/spec/faraday/request_spec.rb:\d+.}
29
29
  end
30
30
 
31
31
  it { expect(subject.method).to eq(:post) }
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Faraday::Response::Json, type: :response do
4
+ let(:options) { {} }
5
+ let(:headers) { {} }
6
+ let(:middleware) do
7
+ described_class.new(lambda { |env|
8
+ Faraday::Response.new(env)
9
+ }, **options)
10
+ end
11
+
12
+ def process(body, content_type = 'application/json', options = {})
13
+ env = {
14
+ body: body, request: options,
15
+ request_headers: Faraday::Utils::Headers.new,
16
+ response_headers: Faraday::Utils::Headers.new(headers)
17
+ }
18
+ env[:response_headers]['content-type'] = content_type if content_type
19
+ yield(env) if block_given?
20
+ middleware.call(Faraday::Env.from(env))
21
+ end
22
+
23
+ context 'no type matching' do
24
+ it "doesn't change nil body" do
25
+ expect(process(nil).body).to be_nil
26
+ end
27
+
28
+ it 'nullifies empty body' do
29
+ expect(process('').body).to be_nil
30
+ end
31
+
32
+ it 'parses json body' do
33
+ response = process('{"a":1}')
34
+ expect(response.body).to eq('a' => 1)
35
+ expect(response.env[:raw_body]).to be_nil
36
+ end
37
+ end
38
+
39
+ context 'with preserving raw' do
40
+ let(:options) { { preserve_raw: true } }
41
+
42
+ it 'parses json body' do
43
+ response = process('{"a":1}')
44
+ expect(response.body).to eq('a' => 1)
45
+ expect(response.env[:raw_body]).to eq('{"a":1}')
46
+ end
47
+ end
48
+
49
+ context 'with default regexp type matching' do
50
+ it 'parses json body of correct type' do
51
+ response = process('{"a":1}', 'application/x-json')
52
+ expect(response.body).to eq('a' => 1)
53
+ end
54
+
55
+ it 'ignores json body of incorrect type' do
56
+ response = process('{"a":1}', 'text/json-xml')
57
+ expect(response.body).to eq('{"a":1}')
58
+ end
59
+ end
60
+
61
+ context 'with array type matching' do
62
+ let(:options) { { content_type: %w[a/b c/d] } }
63
+
64
+ it 'parses json body of correct type' do
65
+ expect(process('{"a":1}', 'a/b').body).to be_a(Hash)
66
+ expect(process('{"a":1}', 'c/d').body).to be_a(Hash)
67
+ end
68
+
69
+ it 'ignores json body of incorrect type' do
70
+ expect(process('{"a":1}', 'a/d').body).not_to be_a(Hash)
71
+ end
72
+ end
73
+
74
+ it 'chokes on invalid json' do
75
+ expect { process('{!') }.to raise_error(Faraday::ParsingError)
76
+ end
77
+
78
+ it 'includes the response on the ParsingError instance' do
79
+ begin
80
+ process('{') { |env| env[:response] = Faraday::Response.new }
81
+ raise 'Parsing should have failed.'
82
+ rescue Faraday::ParsingError => e
83
+ expect(e.response).to be_a(Faraday::Response)
84
+ end
85
+ end
86
+
87
+ context 'HEAD responses' do
88
+ it "nullifies the body if it's only one space" do
89
+ response = process(' ')
90
+ expect(response.body).to be_nil
91
+ end
92
+
93
+ it "nullifies the body if it's two spaces" do
94
+ response = process(' ')
95
+ expect(response.body).to be_nil
96
+ end
97
+ end
98
+
99
+ context 'JSON options' do
100
+ let(:body) { '{"a": 1}' }
101
+ let(:result) { { a: 1 } }
102
+ let(:options) do
103
+ {
104
+ parser_options: {
105
+ symbolize_names: true
106
+ }
107
+ }
108
+ end
109
+
110
+ it 'passes relevant options to JSON parse' do
111
+ expect(::JSON).to receive(:parse)
112
+ .with(body, options[:parser_options])
113
+ .and_return(result)
114
+
115
+ response = process(body)
116
+ expect(response.body).to eq(result)
117
+ end
118
+ end
119
+ end
data/spec/spec_helper.rb CHANGED
@@ -38,6 +38,8 @@ require 'pry'
38
38
 
39
39
  Dir['./spec/support/**/*.rb'].sort.each { |f| require f }
40
40
 
41
+ Faraday::Deprecate.skip = false
42
+
41
43
  RSpec.configure do |config|
42
44
  # rspec-expectations config goes here. You can use an alternate
43
45
  # assertion/expectation library such as wrong or the stdlib/minitest
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: 1.9.3
4
+ version: 1.10.3
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: 2022-01-06 00:00:00.000000000 Z
13
+ date: 2023-01-18 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: faraday-em_http
@@ -186,6 +186,7 @@ files:
186
186
  - lib/faraday/autoload.rb
187
187
  - lib/faraday/connection.rb
188
188
  - lib/faraday/dependency_loader.rb
189
+ - lib/faraday/deprecate.rb
189
190
  - lib/faraday/encoders/flat_params_encoder.rb
190
191
  - lib/faraday/encoders/nested_params_encoder.rb
191
192
  - lib/faraday/error.rb
@@ -205,9 +206,11 @@ files:
205
206
  - lib/faraday/request/authorization.rb
206
207
  - lib/faraday/request/basic_authentication.rb
207
208
  - lib/faraday/request/instrumentation.rb
209
+ - lib/faraday/request/json.rb
208
210
  - lib/faraday/request/token_authentication.rb
209
211
  - lib/faraday/request/url_encoded.rb
210
212
  - lib/faraday/response.rb
213
+ - lib/faraday/response/json.rb
211
214
  - lib/faraday/response/logger.rb
212
215
  - lib/faraday/response/raise_error.rb
213
216
  - lib/faraday/utils.rb
@@ -228,6 +231,7 @@ files:
228
231
  - spec/faraday/adapter_spec.rb
229
232
  - spec/faraday/composite_read_io_spec.rb
230
233
  - spec/faraday/connection_spec.rb
234
+ - spec/faraday/deprecate_spec.rb
231
235
  - spec/faraday/error_spec.rb
232
236
  - spec/faraday/middleware_spec.rb
233
237
  - spec/faraday/options/env_spec.rb
@@ -239,8 +243,10 @@ files:
239
243
  - spec/faraday/rack_builder_spec.rb
240
244
  - spec/faraday/request/authorization_spec.rb
241
245
  - spec/faraday/request/instrumentation_spec.rb
246
+ - spec/faraday/request/json_spec.rb
242
247
  - spec/faraday/request/url_encoded_spec.rb
243
248
  - spec/faraday/request_spec.rb
249
+ - spec/faraday/response/json_spec.rb
244
250
  - spec/faraday/response/logger_spec.rb
245
251
  - spec/faraday/response/middleware_spec.rb
246
252
  - spec/faraday/response/raise_error_spec.rb
@@ -262,7 +268,7 @@ licenses:
262
268
  - MIT
263
269
  metadata:
264
270
  homepage_uri: https://lostisland.github.io/faraday
265
- changelog_uri: https://github.com/lostisland/faraday/releases/tag/v1.9.3
271
+ changelog_uri: https://github.com/lostisland/faraday/releases/tag/v1.10.3
266
272
  source_code_uri: https://github.com/lostisland/faraday
267
273
  bug_tracker_uri: https://github.com/lostisland/faraday/issues
268
274
  post_install_message:
@@ -281,7 +287,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
281
287
  - !ruby/object:Gem::Version
282
288
  version: '0'
283
289
  requirements: []
284
- rubygems_version: 3.0.3.1
290
+ rubygems_version: 3.1.6
285
291
  signing_key:
286
292
  specification_version: 4
287
293
  summary: HTTP/REST API client library.