faraday 0.17.3 → 1.0.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 (133) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +52 -8
  3. data/LICENSE.md +1 -1
  4. data/README.md +18 -358
  5. data/Rakefile +1 -7
  6. data/examples/client_spec.rb +65 -0
  7. data/examples/client_test.rb +79 -0
  8. data/lib/faraday.rb +94 -175
  9. data/lib/faraday/adapter.rb +82 -22
  10. data/lib/faraday/adapter/em_http.rb +142 -99
  11. data/lib/faraday/adapter/em_http_ssl_patch.rb +24 -18
  12. data/lib/faraday/adapter/em_synchrony.rb +104 -60
  13. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +18 -15
  14. data/lib/faraday/adapter/excon.rb +98 -56
  15. data/lib/faraday/adapter/httpclient.rb +83 -59
  16. data/lib/faraday/adapter/net_http.rb +130 -63
  17. data/lib/faraday/adapter/net_http_persistent.rb +50 -27
  18. data/lib/faraday/adapter/patron.rb +80 -43
  19. data/lib/faraday/adapter/rack.rb +30 -13
  20. data/lib/faraday/adapter/test.rb +86 -53
  21. data/lib/faraday/adapter/typhoeus.rb +4 -1
  22. data/lib/faraday/adapter_registry.rb +30 -0
  23. data/lib/faraday/autoload.rb +47 -36
  24. data/lib/faraday/connection.rb +312 -182
  25. data/lib/faraday/dependency_loader.rb +37 -0
  26. data/lib/faraday/encoders/flat_params_encoder.rb +98 -0
  27. data/lib/faraday/encoders/nested_params_encoder.rb +171 -0
  28. data/lib/faraday/error.rb +9 -35
  29. data/lib/faraday/file_part.rb +128 -0
  30. data/lib/faraday/logging/formatter.rb +105 -0
  31. data/lib/faraday/middleware.rb +12 -28
  32. data/lib/faraday/middleware_registry.rb +129 -0
  33. data/lib/faraday/options.rb +32 -183
  34. data/lib/faraday/options/connection_options.rb +22 -0
  35. data/lib/faraday/options/env.rb +181 -0
  36. data/lib/faraday/options/proxy_options.rb +28 -0
  37. data/lib/faraday/options/request_options.rb +22 -0
  38. data/lib/faraday/options/ssl_options.rb +59 -0
  39. data/lib/faraday/param_part.rb +53 -0
  40. data/lib/faraday/parameters.rb +4 -197
  41. data/lib/faraday/rack_builder.rb +66 -55
  42. data/lib/faraday/request.rb +68 -36
  43. data/lib/faraday/request/authorization.rb +44 -30
  44. data/lib/faraday/request/basic_authentication.rb +14 -7
  45. data/lib/faraday/request/instrumentation.rb +45 -27
  46. data/lib/faraday/request/multipart.rb +79 -48
  47. data/lib/faraday/request/retry.rb +197 -171
  48. data/lib/faraday/request/token_authentication.rb +15 -10
  49. data/lib/faraday/request/url_encoded.rb +43 -23
  50. data/lib/faraday/response.rb +24 -14
  51. data/lib/faraday/response/logger.rb +22 -69
  52. data/lib/faraday/response/raise_error.rb +38 -18
  53. data/lib/faraday/utils.rb +36 -245
  54. data/lib/faraday/utils/headers.rb +139 -0
  55. data/lib/faraday/utils/params_hash.rb +61 -0
  56. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  57. data/spec/faraday/adapter/em_http_spec.rb +47 -0
  58. data/spec/faraday/adapter/em_synchrony_spec.rb +16 -0
  59. data/spec/faraday/adapter/excon_spec.rb +49 -0
  60. data/spec/faraday/adapter/httpclient_spec.rb +73 -0
  61. data/spec/faraday/adapter/net_http_persistent_spec.rb +57 -0
  62. data/spec/faraday/adapter/net_http_spec.rb +64 -0
  63. data/spec/faraday/adapter/patron_spec.rb +18 -0
  64. data/spec/faraday/adapter/rack_spec.rb +8 -0
  65. data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
  66. data/spec/faraday/adapter_registry_spec.rb +28 -0
  67. data/spec/faraday/adapter_spec.rb +55 -0
  68. data/spec/faraday/composite_read_io_spec.rb +80 -0
  69. data/spec/faraday/connection_spec.rb +691 -0
  70. data/spec/faraday/error_spec.rb +0 -57
  71. data/spec/faraday/middleware_spec.rb +26 -0
  72. data/spec/faraday/options/env_spec.rb +70 -0
  73. data/spec/faraday/options/options_spec.rb +297 -0
  74. data/spec/faraday/options/proxy_options_spec.rb +37 -0
  75. data/spec/faraday/options/request_options_spec.rb +19 -0
  76. data/spec/faraday/params_encoders/flat_spec.rb +34 -0
  77. data/spec/faraday/params_encoders/nested_spec.rb +134 -0
  78. data/spec/faraday/rack_builder_spec.rb +196 -0
  79. data/spec/faraday/request/authorization_spec.rb +88 -0
  80. data/spec/faraday/request/instrumentation_spec.rb +76 -0
  81. data/spec/faraday/request/multipart_spec.rb +274 -0
  82. data/spec/faraday/request/retry_spec.rb +242 -0
  83. data/spec/faraday/request/url_encoded_spec.rb +83 -0
  84. data/spec/faraday/request_spec.rb +109 -0
  85. data/spec/faraday/response/logger_spec.rb +220 -0
  86. data/spec/faraday/response/middleware_spec.rb +68 -0
  87. data/spec/faraday/response/raise_error_spec.rb +15 -15
  88. data/spec/faraday/response_spec.rb +75 -0
  89. data/spec/faraday/utils/headers_spec.rb +82 -0
  90. data/spec/faraday/utils_spec.rb +56 -0
  91. data/spec/faraday_spec.rb +37 -0
  92. data/spec/spec_helper.rb +63 -36
  93. data/spec/support/disabling_stub.rb +14 -0
  94. data/spec/support/fake_safe_buffer.rb +15 -0
  95. data/spec/support/helper_methods.rb +133 -0
  96. data/spec/support/shared_examples/adapter.rb +104 -0
  97. data/spec/support/shared_examples/params_encoder.rb +18 -0
  98. data/spec/support/shared_examples/request_method.rb +234 -0
  99. data/spec/support/streaming_response_checker.rb +35 -0
  100. data/spec/support/webmock_rack_app.rb +68 -0
  101. metadata +66 -38
  102. data/lib/faraday/deprecate.rb +0 -107
  103. data/lib/faraday/upload_io.rb +0 -67
  104. data/spec/faraday/deprecate_spec.rb +0 -69
  105. data/test/adapters/default_test.rb +0 -14
  106. data/test/adapters/em_http_test.rb +0 -30
  107. data/test/adapters/em_synchrony_test.rb +0 -32
  108. data/test/adapters/excon_test.rb +0 -30
  109. data/test/adapters/httpclient_test.rb +0 -34
  110. data/test/adapters/integration.rb +0 -263
  111. data/test/adapters/logger_test.rb +0 -136
  112. data/test/adapters/net_http_persistent_test.rb +0 -114
  113. data/test/adapters/net_http_test.rb +0 -79
  114. data/test/adapters/patron_test.rb +0 -40
  115. data/test/adapters/rack_test.rb +0 -38
  116. data/test/adapters/test_middleware_test.rb +0 -157
  117. data/test/adapters/typhoeus_test.rb +0 -38
  118. data/test/authentication_middleware_test.rb +0 -65
  119. data/test/composite_read_io_test.rb +0 -109
  120. data/test/connection_test.rb +0 -738
  121. data/test/env_test.rb +0 -268
  122. data/test/helper.rb +0 -75
  123. data/test/live_server.rb +0 -67
  124. data/test/middleware/instrumentation_test.rb +0 -88
  125. data/test/middleware/retry_test.rb +0 -282
  126. data/test/middleware_stack_test.rb +0 -260
  127. data/test/multibyte.txt +0 -1
  128. data/test/options_test.rb +0 -333
  129. data/test/parameters_test.rb +0 -157
  130. data/test/request_middleware_test.rb +0 -126
  131. data/test/response_middleware_test.rb +0 -72
  132. data/test/strawberry.rb +0 -2
  133. data/test/utils_test.rb +0 -98
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
5
+ # Net::HTTP::Persistent adapter.
3
6
  class NetHttpPersistent < NetHttp
4
7
  dependency 'net/http/persistent'
5
8
 
@@ -7,61 +10,81 @@ module Faraday
7
10
 
8
11
  def net_http_connection(env)
9
12
  @cached_connection ||=
10
- if Net::HTTP::Persistent.instance_method(:initialize).parameters.first == [:key, :name]
11
- options = {name: 'Faraday'}
12
- options[:pool_size] = @connection_options[:pool_size] if @connection_options.key?(:pool_size)
13
+ if Net::HTTP::Persistent.instance_method(:initialize)
14
+ .parameters.first == %i[key name]
15
+ options = { name: 'Faraday' }
16
+ if @connection_options.key?(:pool_size)
17
+ options[:pool_size] = @connection_options[:pool_size]
18
+ end
13
19
  Net::HTTP::Persistent.new(**options)
14
20
  else
15
21
  Net::HTTP::Persistent.new('Faraday')
16
22
  end
17
23
 
18
24
  proxy_uri = proxy_uri(env)
19
- @cached_connection.proxy = proxy_uri if @cached_connection.proxy_uri != proxy_uri
25
+ if @cached_connection.proxy_uri != proxy_uri
26
+ @cached_connection.proxy = proxy_uri
27
+ end
20
28
  @cached_connection
21
29
  end
22
30
 
23
31
  def proxy_uri(env)
24
32
  proxy_uri = nil
25
33
  if (proxy = env[:request][:proxy])
26
- proxy_uri = ::URI::HTTP === proxy[:uri] ? proxy[:uri].dup : ::URI.parse(proxy[:uri].to_s)
34
+ proxy_uri = if proxy[:uri].is_a?(::URI::HTTP)
35
+ proxy[:uri].dup
36
+ else
37
+ ::URI.parse(proxy[:uri].to_s)
38
+ end
27
39
  proxy_uri.user = proxy_uri.password = nil
28
- # awful patch for net-http-persistent 2.8 not unescaping user/password
29
- (class << proxy_uri; self; end).class_eval do
30
- define_method(:user) { proxy[:user] }
31
- define_method(:password) { proxy[:password] }
32
- end if proxy[:user]
40
+ # awful patch for net-http-persistent 2.8
41
+ # not unescaping user/password
42
+ if proxy[:user]
43
+ (class << proxy_uri; self; end).class_eval do
44
+ define_method(:user) { proxy[:user] }
45
+ define_method(:password) { proxy[:password] }
46
+ end
47
+ end
33
48
  end
34
49
  proxy_uri
35
50
  end
36
51
 
37
52
  def perform_request(http, env)
38
53
  http.request env[:url], create_request(env)
39
- rescue Errno::ETIMEDOUT => error
40
- raise Faraday::TimeoutError, error
41
- rescue Net::HTTP::Persistent::Error => error
42
- if error.message.include? 'Timeout'
43
- raise Faraday::TimeoutError, error
44
- elsif error.message.include? 'connection refused'
45
- raise Faraday::ConnectionFailed, error
46
- else
47
- raise
54
+ rescue Errno::ETIMEDOUT => e
55
+ raise Faraday::TimeoutError, e
56
+ rescue Net::HTTP::Persistent::Error => e
57
+ raise Faraday::TimeoutError, e if e.message.include? 'Timeout'
58
+
59
+ if e.message.include? 'connection refused'
60
+ raise Faraday::ConnectionFailed, e
48
61
  end
62
+
63
+ raise
49
64
  end
50
65
 
66
+ SSL_CONFIGURATIONS = {
67
+ certificate: :client_cert,
68
+ private_key: :client_key,
69
+ ca_file: :ca_file,
70
+ ssl_version: :version,
71
+ min_version: :min_version,
72
+ max_version: :max_version
73
+ }.freeze
74
+
51
75
  def configure_ssl(http, ssl)
76
+ return unless ssl
77
+
52
78
  http_set(http, :verify_mode, ssl_verify_mode(ssl))
53
- http_set(http, :cert_store, ssl_cert_store(ssl))
79
+ http_set(http, :cert_store, ssl_cert_store(ssl))
54
80
 
55
- http_set(http, :certificate, ssl[:client_cert]) if ssl[:client_cert]
56
- http_set(http, :private_key, ssl[:client_key]) if ssl[:client_key]
57
- http_set(http, :ca_file, ssl[:ca_file]) if ssl[:ca_file]
58
- http_set(http, :ssl_version, ssl[:version]) if ssl[:version]
81
+ SSL_CONFIGURATIONS
82
+ .select { |_, key| ssl[key] }
83
+ .each { |target, key| http_set(http, target, ssl[key]) }
59
84
  end
60
85
 
61
86
  def http_set(http, attr, value)
62
- if http.send(attr) != value
63
- http.send("#{attr}=", value)
64
- end
87
+ http.send("#{attr}=", value) if http.send(attr) != value
65
88
  end
66
89
  end
67
90
  end
@@ -1,54 +1,66 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
5
+ # Patron adapter.
3
6
  class Patron < Faraday::Adapter
4
7
  dependency 'patron'
5
8
 
9
+ def build_connection(env)
10
+ session = ::Patron::Session.new
11
+ @config_block&.call(session)
12
+ if (env[:url].scheme == 'https') && env[:ssl]
13
+ configure_ssl(session, env[:ssl])
14
+ end
15
+
16
+ if (req = env[:request])
17
+ configure_timeouts(session, req)
18
+ configure_proxy(session, req[:proxy])
19
+ end
20
+
21
+ session
22
+ end
23
+
6
24
  def call(env)
7
25
  super
8
26
  # TODO: support streaming requests
9
27
  env[:body] = env[:body].read if env[:body].respond_to? :read
10
28
 
11
- session = ::Patron::Session.new
12
- @config_block.call(session) if @config_block
13
- configure_ssl(session, env[:ssl]) if env[:url].scheme == 'https' and env[:ssl]
14
-
15
- if req = env[:request]
16
- session.timeout = session.connect_timeout = req[:timeout] if req[:timeout]
17
- session.connect_timeout = req[:open_timeout] if req[:open_timeout]
18
-
19
- if proxy = req[:proxy]
20
- proxy_uri = proxy[:uri].dup
21
- proxy_uri.user = proxy[:user] && Utils.escape(proxy[:user]).gsub('+', '%20')
22
- proxy_uri.password = proxy[:password] && Utils.escape(proxy[:password]).gsub('+', '%20')
23
- session.proxy = proxy_uri.to_s
29
+ response = connection(env) do |session|
30
+ begin
31
+ data = env[:body] ? env[:body].to_s : nil
32
+ session.request(env[:method], env[:url].to_s,
33
+ env[:request_headers], data: data)
34
+ rescue Errno::ECONNREFUSED, ::Patron::ConnectionFailed
35
+ raise Faraday::ConnectionFailed, $ERROR_INFO
24
36
  end
25
37
  end
26
38
 
27
- response = begin
28
- data = env[:body] ? env[:body].to_s : nil
29
- session.request(env[:method], env[:url].to_s, env[:request_headers], :data => data)
30
- rescue Errno::ECONNREFUSED, ::Patron::ConnectionFailed
31
- raise Faraday::ConnectionFailed, $!
39
+ if (req = env[:request]).stream_response?
40
+ warn "Streaming downloads for #{self.class.name} " \
41
+ 'are not yet implemented.'
42
+ req.on_data.call(response.body, response.body.bytesize)
32
43
  end
33
-
34
44
  # Remove the "HTTP/1.1 200", leaving just the reason phrase
35
45
  reason_phrase = response.status_line.gsub(/^.* \d{3} /, '')
36
46
 
37
- save_response(env, response.status, response.body, response.headers, reason_phrase)
47
+ save_response(env, response.status, response.body,
48
+ response.headers, reason_phrase)
38
49
 
39
50
  @app.call env
40
- rescue ::Patron::TimeoutError => err
41
- if connection_timed_out_message?(err.message)
42
- raise Faraday::ConnectionFailed, err
43
- else
44
- raise Faraday::TimeoutError, err
51
+ rescue ::Patron::TimeoutError => e
52
+ if connection_timed_out_message?(e.message)
53
+ raise Faraday::ConnectionFailed, e
45
54
  end
46
- rescue ::Patron::Error => err
47
- if err.message.include?("code 407")
48
- raise Faraday::ConnectionFailed, %{407 "Proxy Authentication Required "}
49
- else
50
- raise Faraday::ConnectionFailed, err
55
+
56
+ raise Faraday::TimeoutError, e
57
+ rescue ::Patron::Error => e
58
+ if e.message.include?('code 407')
59
+ raise Faraday::ConnectionFailed,
60
+ %(407 "Proxy Authentication Required ")
51
61
  end
62
+
63
+ raise Faraday::ConnectionFailed, e
52
64
  end
53
65
 
54
66
  if loaded? && defined?(::Patron::Request::VALID_ACTIONS)
@@ -60,8 +72,8 @@ module Faraday
60
72
  actions << :options unless actions.include? :options
61
73
  else
62
74
  # Patron 0.4.20 and up
63
- actions << "PATCH" unless actions.include? "PATCH"
64
- actions << "OPTIONS" unless actions.include? "OPTIONS"
75
+ actions << 'PATCH' unless actions.include? 'PATCH'
76
+ actions << 'OPTIONS' unless actions.include? 'OPTIONS'
65
77
  end
66
78
  end
67
79
  end
@@ -74,22 +86,47 @@ module Faraday
74
86
  end
75
87
  end
76
88
 
89
+ def configure_timeouts(session, req)
90
+ return unless req
91
+
92
+ if (sec = request_timeout(:read, req))
93
+ session.timeout = sec
94
+ end
95
+
96
+ return unless (sec = request_timeout(:open, req))
97
+
98
+ session.connect_timeout = sec
99
+ end
100
+
101
+ def configure_proxy(session, proxy)
102
+ return unless proxy
103
+
104
+ proxy_uri = proxy[:uri].dup
105
+ proxy_uri.user = proxy[:user] &&
106
+ Utils.escape(proxy[:user]).gsub('+', '%20')
107
+ proxy_uri.password = proxy[:password] &&
108
+ Utils.escape(proxy[:password]).gsub('+', '%20')
109
+ session.proxy = proxy_uri.to_s
110
+ end
111
+
77
112
  private
78
113
 
79
- CURL_TIMEOUT_MESSAGES = [ "Connection time-out",
80
- "Connection timed out",
81
- "Timed out before name resolve",
82
- "server connect has timed out",
83
- "Resolving timed out",
84
- "name lookup timed out",
85
- "timed out before SSL",
86
- "connect() timed out"
87
- ].freeze
114
+ CURL_TIMEOUT_MESSAGES = [
115
+ 'Connection time-out',
116
+ 'Connection timed out',
117
+ 'Timed out before name resolve',
118
+ 'server connect has timed out',
119
+ 'Resolving timed out',
120
+ 'name lookup timed out',
121
+ 'timed out before SSL',
122
+ 'connect() timed out'
123
+ ].freeze
88
124
 
89
125
  def connection_timed_out_message?(message)
90
- CURL_TIMEOUT_MESSAGES.any? { |curl_message| message.include?(curl_message) }
126
+ CURL_TIMEOUT_MESSAGES.any? do |curl_message|
127
+ message.include?(curl_message)
128
+ end
91
129
  end
92
-
93
130
  end
94
131
  end
95
132
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
3
5
  # Sends requests to a Rack app.
4
6
  #
5
- # Examples
7
+ # @example
6
8
  #
7
9
  # class MyRackApp
8
10
  # def call(env)
@@ -17,7 +19,7 @@ module Faraday
17
19
  dependency 'rack/test'
18
20
 
19
21
  # not prefixed with "HTTP_"
20
- SPECIAL_HEADERS = %w[ CONTENT_LENGTH CONTENT_TYPE ]
22
+ SPECIAL_HEADERS = %w[CONTENT_LENGTH CONTENT_TYPE].freeze
21
23
 
22
24
  def initialize(faraday_app, rack_app)
23
25
  super(faraday_app)
@@ -27,32 +29,47 @@ module Faraday
27
29
 
28
30
  def call(env)
29
31
  super
30
- rack_env = {
31
- :method => env[:method],
32
- :input => env[:body].respond_to?(:read) ? env[:body].read : env[:body],
33
- 'rack.url_scheme' => env[:url].scheme
34
- }
32
+ rack_env = build_rack_env(env)
35
33
 
36
- env[:request_headers].each do |name, value|
34
+ env[:request_headers]&.each do |name, value|
37
35
  name = name.upcase.tr('-', '_')
38
36
  name = "HTTP_#{name}" unless SPECIAL_HEADERS.include? name
39
37
  rack_env[name] = value
40
- end if env[:request_headers]
38
+ end
41
39
 
42
- timeout = env[:request][:timeout] || env[:request][:open_timeout]
40
+ timeout = request_timeout(:open, env[:request])
41
+ timeout ||= request_timeout(:read, env[:request])
43
42
  response = if timeout
44
- Timer.timeout(timeout, Faraday::TimeoutError) { execute_request(env, rack_env) }
45
- else
46
- execute_request(env, rack_env)
43
+ Timer.timeout(timeout, Faraday::TimeoutError) do
44
+ execute_request(env, rack_env)
45
+ end
46
+ else
47
+ execute_request(env, rack_env)
48
+ end
49
+
50
+ if (req = env[:request]).stream_response?
51
+ warn "Streaming downloads for #{self.class.name} " \
52
+ 'are not yet implemented.'
53
+ req.on_data.call(response.body, response.body.bytesize)
47
54
  end
48
55
 
49
56
  save_response(env, response.status, response.body, response.headers)
50
57
  @app.call env
51
58
  end
52
59
 
60
+ private
61
+
53
62
  def execute_request(env, rack_env)
54
63
  @session.request(env[:url].to_s, rack_env)
55
64
  end
65
+
66
+ def build_rack_env(env)
67
+ {
68
+ method: env[:method],
69
+ input: env[:body].respond_to?(:read) ? env[:body].read : env[:body],
70
+ 'rack.url_scheme' => env[:url].scheme
71
+ }
72
+ end
56
73
  end
57
74
  end
58
75
  end
@@ -1,51 +1,56 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
3
- # Examples
4
- #
5
+ # @example
5
6
  # test = Faraday::Connection.new do
6
7
  # use Faraday::Adapter::Test do |stub|
7
- # # simply define matcher to match the request
8
+ # # Define matcher to match the request
8
9
  # stub.get '/resource.json' do
9
10
  # # return static content
10
11
  # [200, {'Content-Type' => 'application/json'}, 'hi world']
11
12
  # end
12
- #
13
+ #
13
14
  # # response with content generated based on request
14
15
  # stub.get '/showget' do |env|
15
16
  # [200, {'Content-Type' => 'text/plain'}, env[:method].to_s]
16
17
  # end
17
- #
18
- # # regular expression can be used as matching filter
18
+ #
19
+ # # A regular expression can be used as matching filter
19
20
  # stub.get /\A\/items\/(\d+)\z/ do |env, meta|
20
- # # in case regular expression is used an instance of MatchData can be received
21
- # [200, {'Content-Type' => 'text/plain'}, "showing item: #{meta[:match_data][1]}"]
21
+ # # in case regular expression is used, an instance of MatchData
22
+ # # can be received
23
+ # [200,
24
+ # {'Content-Type' => 'text/plain'},
25
+ # "showing item: #{meta[:match_data][1]}"
26
+ # ]
22
27
  # end
23
28
  # end
24
29
  # end
25
- #
30
+ #
26
31
  # resp = test.get '/resource.json'
27
32
  # resp.body # => 'hi world'
28
- #
33
+ #
29
34
  # resp = test.get '/showget'
30
35
  # resp.body # => 'get'
31
- #
36
+ #
32
37
  # resp = test.get '/items/1'
33
38
  # resp.body # => 'showing item: 1'
34
- #
39
+ #
35
40
  # resp = test.get '/items/2'
36
41
  # resp.body # => 'showing item: 2'
37
- #
38
-
39
42
  class Test < Faraday::Adapter
40
43
  attr_accessor :stubs
41
44
 
45
+ # A stack of Stubs
42
46
  class Stubs
43
47
  class NotFound < StandardError
44
48
  end
45
49
 
46
50
  def initialize
47
- # {:get => [Stub, Stub]}
48
- @stack, @consumed = {}, {}
51
+ # { get: [Stub, Stub] }
52
+ @stack = {}
53
+ @consumed = {}
49
54
  yield(self) if block_given?
50
55
  end
51
56
 
@@ -54,7 +59,8 @@ module Faraday
54
59
  end
55
60
 
56
61
  def match(request_method, host, path, headers, body)
57
- return false if !@stack.key?(request_method)
62
+ return false unless @stack.key?(request_method)
63
+
58
64
  stack = @stack[request_method]
59
65
  consumed = (@consumed[request_method] ||= [])
60
66
 
@@ -74,15 +80,15 @@ module Faraday
74
80
  new_stub(:head, path, headers, &block)
75
81
  end
76
82
 
77
- def post(path, body=nil, headers = {}, &block)
83
+ def post(path, body = nil, headers = {}, &block)
78
84
  new_stub(:post, path, headers, body, &block)
79
85
  end
80
86
 
81
- def put(path, body=nil, headers = {}, &block)
87
+ def put(path, body = nil, headers = {}, &block)
82
88
  new_stub(:put, path, headers, body, &block)
83
89
  end
84
90
 
85
- def patch(path, body=nil, headers = {}, &block)
91
+ def patch(path, body = nil, headers = {}, &block)
86
92
  new_stub(:patch, path, headers, body, &block)
87
93
  end
88
94
 
@@ -98,26 +104,32 @@ module Faraday
98
104
  def verify_stubbed_calls
99
105
  failed_stubs = []
100
106
  @stack.each do |method, stubs|
101
- unless stubs.size == 0
102
- failed_stubs.concat(stubs.map {|stub|
107
+ next if stubs.empty?
108
+
109
+ failed_stubs.concat(
110
+ stubs.map do |stub|
103
111
  "Expected #{method} #{stub}."
104
- })
105
- end
112
+ end
113
+ )
106
114
  end
107
- raise failed_stubs.join(" ") unless failed_stubs.size == 0
115
+ raise failed_stubs.join(' ') unless failed_stubs.empty?
108
116
  end
109
117
 
110
118
  protected
111
119
 
112
- def new_stub(request_method, path, headers = {}, body=nil, &block)
120
+ def new_stub(request_method, path, headers = {}, body = nil, &block)
113
121
  normalized_path, host =
114
122
  if path.is_a?(Regexp)
115
123
  path
116
124
  else
117
- [Faraday::Utils.normalize_path(path), Faraday::Utils.URI(path).host]
125
+ [
126
+ Faraday::Utils.normalize_path(path),
127
+ Faraday::Utils.URI(path).host
128
+ ]
118
129
  end
119
130
 
120
- (@stack[request_method] ||= []) << Stub.new(host, normalized_path, headers, body, block)
131
+ stub = Stub.new(host, normalized_path, headers, body, block)
132
+ (@stack[request_method] ||= []) << stub
121
133
  end
122
134
 
123
135
  def matches?(stack, host, path, headers, body)
@@ -129,32 +141,42 @@ module Faraday
129
141
  end
130
142
  end
131
143
 
144
+ # Stub request
145
+ # rubocop:disable Style/StructInheritance
132
146
  class Stub < Struct.new(:host, :path, :params, :headers, :body, :block)
147
+ # rubocop:enable Style/StructInheritance
133
148
  def initialize(host, full, headers, body, block)
134
- path, query = full.respond_to?(:split) ? full.split("?") : full
135
- params = query ?
136
- Faraday::Utils.parse_nested_query(query) :
137
- {}
149
+ path, query = full.respond_to?(:split) ? full.split('?') : full
150
+ params =
151
+ if query
152
+ Faraday::Utils.parse_nested_query(query)
153
+ else
154
+ {}
155
+ end
156
+
138
157
  super(host, path, params, headers, body, block)
139
158
  end
140
159
 
141
160
  def matches?(request_host, request_uri, request_headers, request_body)
142
161
  request_path, request_query = request_uri.split('?')
143
- request_params = request_query ?
144
- Faraday::Utils.parse_nested_query(request_query) :
145
- {}
146
- # meta is a hash use as carrier
162
+ request_params =
163
+ if request_query
164
+ Faraday::Utils.parse_nested_query(request_query)
165
+ else
166
+ {}
167
+ end
168
+ # meta is a hash used as carrier
147
169
  # that will be yielded to consumer block
148
170
  meta = {}
149
- return (host.nil? || host == request_host) &&
171
+ [(host.nil? || host == request_host) &&
150
172
  path_match?(request_path, meta) &&
151
173
  params_match?(request_params) &&
152
174
  (body.to_s.size.zero? || request_body == body) &&
153
- headers_match?(request_headers), meta
175
+ headers_match?(request_headers), meta]
154
176
  end
155
177
 
156
178
  def path_match?(request_path, meta)
157
- if path.is_a? Regexp
179
+ if path.is_a?(Regexp)
158
180
  !!(meta[:match_data] = path.match(request_path))
159
181
  else
160
182
  path == request_path
@@ -178,7 +200,7 @@ module Faraday
178
200
  end
179
201
  end
180
202
 
181
- def initialize(app, stubs=nil, &block)
203
+ def initialize(app, stubs = nil, &block)
182
204
  super(app)
183
205
  @stubs = stubs || Stubs.new
184
206
  configure(&block) if block
@@ -192,20 +214,31 @@ module Faraday
192
214
  super
193
215
  host = env[:url].host
194
216
  normalized_path = Faraday::Utils.normalize_path(env[:url])
195
- params_encoder = env.request.params_encoder || Faraday::Utils.default_params_encoder
196
-
197
- stub, meta = stubs.match(env[:method], host, normalized_path, env.request_headers, env[:body])
198
- if stub
199
- env[:params] = (query = env[:url].query) ?
200
- params_encoder.decode(query) : {}
201
- block_arity = stub.block.arity
202
- status, headers, body = (block_arity >= 0) ?
203
- stub.block.call(*[env, meta].take(block_arity)) :
217
+ params_encoder = env.request.params_encoder ||
218
+ Faraday::Utils.default_params_encoder
219
+
220
+ stub, meta = stubs.match(env[:method], host, normalized_path,
221
+ env.request_headers, env[:body])
222
+
223
+ unless stub
224
+ raise Stubs::NotFound, "no stubbed request for #{env[:method]} "\
225
+ "#{normalized_path} #{env[:body]}"
226
+ end
227
+
228
+ env[:params] = if (query = env[:url].query)
229
+ params_encoder.decode(query)
230
+ else
231
+ {}
232
+ end
233
+ block_arity = stub.block.arity
234
+ status, headers, body =
235
+ if block_arity >= 0
236
+ stub.block.call(*[env, meta].take(block_arity))
237
+ else
204
238
  stub.block.call(env, meta)
205
- save_response(env, status, body, headers)
206
- else
207
- raise Stubs::NotFound, "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}"
208
- end
239
+ end
240
+ save_response(env, status, body, headers)
241
+
209
242
  @app.call(env)
210
243
  end
211
244
  end