faraday 0.17.3 → 1.0.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.
Files changed (134) 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/UPGRADING.md +55 -0
  7. data/examples/client_spec.rb +65 -0
  8. data/examples/client_test.rb +79 -0
  9. data/lib/faraday/adapter/em_http.rb +141 -99
  10. data/lib/faraday/adapter/em_http_ssl_patch.rb +24 -18
  11. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +18 -15
  12. data/lib/faraday/adapter/em_synchrony.rb +104 -60
  13. data/lib/faraday/adapter/excon.rb +98 -56
  14. data/lib/faraday/adapter/httpclient.rb +82 -59
  15. data/lib/faraday/adapter/net_http.rb +119 -62
  16. data/lib/faraday/adapter/net_http_persistent.rb +50 -27
  17. data/lib/faraday/adapter/patron.rb +80 -43
  18. data/lib/faraday/adapter/rack.rb +30 -13
  19. data/lib/faraday/adapter/test.rb +86 -53
  20. data/lib/faraday/adapter/typhoeus.rb +4 -1
  21. data/lib/faraday/adapter.rb +82 -22
  22. data/lib/faraday/adapter_registry.rb +28 -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/connection_options.rb +22 -0
  34. data/lib/faraday/options/env.rb +181 -0
  35. data/lib/faraday/options/proxy_options.rb +28 -0
  36. data/lib/faraday/options/request_options.rb +22 -0
  37. data/lib/faraday/options/ssl_options.rb +59 -0
  38. data/lib/faraday/options.rb +32 -183
  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/authorization.rb +42 -30
  43. data/lib/faraday/request/basic_authentication.rb +14 -7
  44. data/lib/faraday/request/instrumentation.rb +45 -27
  45. data/lib/faraday/request/multipart.rb +79 -48
  46. data/lib/faraday/request/retry.rb +197 -171
  47. data/lib/faraday/request/token_authentication.rb +15 -10
  48. data/lib/faraday/request/url_encoded.rb +41 -23
  49. data/lib/faraday/request.rb +68 -36
  50. data/lib/faraday/response/logger.rb +22 -69
  51. data/lib/faraday/response/raise_error.rb +38 -18
  52. data/lib/faraday/response.rb +20 -13
  53. data/lib/faraday/utils/headers.rb +139 -0
  54. data/lib/faraday/utils/params_hash.rb +61 -0
  55. data/lib/faraday/utils.rb +28 -245
  56. data/lib/faraday.rb +93 -174
  57. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  58. data/spec/faraday/adapter/em_http_spec.rb +47 -0
  59. data/spec/faraday/adapter/em_synchrony_spec.rb +16 -0
  60. data/spec/faraday/adapter/excon_spec.rb +49 -0
  61. data/spec/faraday/adapter/httpclient_spec.rb +73 -0
  62. data/spec/faraday/adapter/net_http_persistent_spec.rb +57 -0
  63. data/spec/faraday/adapter/net_http_spec.rb +64 -0
  64. data/spec/faraday/adapter/patron_spec.rb +18 -0
  65. data/spec/faraday/adapter/rack_spec.rb +8 -0
  66. data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
  67. data/spec/faraday/adapter_registry_spec.rb +28 -0
  68. data/spec/faraday/adapter_spec.rb +55 -0
  69. data/spec/faraday/composite_read_io_spec.rb +80 -0
  70. data/spec/faraday/connection_spec.rb +691 -0
  71. data/spec/faraday/error_spec.rb +0 -57
  72. data/spec/faraday/middleware_spec.rb +26 -0
  73. data/spec/faraday/options/env_spec.rb +70 -0
  74. data/spec/faraday/options/options_spec.rb +297 -0
  75. data/spec/faraday/options/proxy_options_spec.rb +37 -0
  76. data/spec/faraday/options/request_options_spec.rb +19 -0
  77. data/spec/faraday/params_encoders/flat_spec.rb +34 -0
  78. data/spec/faraday/params_encoders/nested_spec.rb +134 -0
  79. data/spec/faraday/rack_builder_spec.rb +196 -0
  80. data/spec/faraday/request/authorization_spec.rb +88 -0
  81. data/spec/faraday/request/instrumentation_spec.rb +76 -0
  82. data/spec/faraday/request/multipart_spec.rb +274 -0
  83. data/spec/faraday/request/retry_spec.rb +242 -0
  84. data/spec/faraday/request/url_encoded_spec.rb +70 -0
  85. data/spec/faraday/request_spec.rb +109 -0
  86. data/spec/faraday/response/logger_spec.rb +220 -0
  87. data/spec/faraday/response/middleware_spec.rb +52 -0
  88. data/spec/faraday/response/raise_error_spec.rb +15 -15
  89. data/spec/faraday/response_spec.rb +75 -0
  90. data/spec/faraday/utils/headers_spec.rb +82 -0
  91. data/spec/faraday/utils_spec.rb +56 -0
  92. data/spec/faraday_spec.rb +37 -0
  93. data/spec/spec_helper.rb +63 -36
  94. data/spec/support/disabling_stub.rb +14 -0
  95. data/spec/support/fake_safe_buffer.rb +15 -0
  96. data/spec/support/helper_methods.rb +133 -0
  97. data/spec/support/shared_examples/adapter.rb +104 -0
  98. data/spec/support/shared_examples/params_encoder.rb +18 -0
  99. data/spec/support/shared_examples/request_method.rb +234 -0
  100. data/spec/support/streaming_response_checker.rb +35 -0
  101. data/spec/support/webmock_rack_app.rb +68 -0
  102. metadata +65 -37
  103. data/lib/faraday/deprecate.rb +0 -107
  104. data/lib/faraday/upload_io.rb +0 -67
  105. data/spec/faraday/deprecate_spec.rb +0 -69
  106. data/test/adapters/default_test.rb +0 -14
  107. data/test/adapters/em_http_test.rb +0 -30
  108. data/test/adapters/em_synchrony_test.rb +0 -32
  109. data/test/adapters/excon_test.rb +0 -30
  110. data/test/adapters/httpclient_test.rb +0 -34
  111. data/test/adapters/integration.rb +0 -263
  112. data/test/adapters/logger_test.rb +0 -136
  113. data/test/adapters/net_http_persistent_test.rb +0 -114
  114. data/test/adapters/net_http_test.rb +0 -79
  115. data/test/adapters/patron_test.rb +0 -40
  116. data/test/adapters/rack_test.rb +0 -38
  117. data/test/adapters/test_middleware_test.rb +0 -157
  118. data/test/adapters/typhoeus_test.rb +0 -38
  119. data/test/authentication_middleware_test.rb +0 -65
  120. data/test/composite_read_io_test.rb +0 -109
  121. data/test/connection_test.rb +0 -738
  122. data/test/env_test.rb +0 -268
  123. data/test/helper.rb +0 -75
  124. data/test/live_server.rb +0 -67
  125. data/test/middleware/instrumentation_test.rb +0 -88
  126. data/test/middleware/retry_test.rb +0 -282
  127. data/test/middleware_stack_test.rb +0 -260
  128. data/test/multibyte.txt +0 -1
  129. data/test/options_test.rb +0 -333
  130. data/test/parameters_test.rb +0 -157
  131. data/test/request_middleware_test.rb +0 -126
  132. data/test/response_middleware_test.rb +0 -72
  133. data/test/strawberry.rb +0 -2
  134. data/test/utils_test.rb +0 -98
@@ -24,24 +24,24 @@ RSpec.describe Faraday::Response::RaiseError do
24
24
  expect { conn.get('ok') }.not_to raise_error
25
25
  end
26
26
 
27
- it 'raises Faraday::ClientError for 400 responses' do
28
- expect { conn.get('bad-request') }.to raise_error(Faraday::ClientError) do |ex|
27
+ it 'raises Faraday::BadRequestError for 400 responses' do
28
+ expect { conn.get('bad-request') }.to raise_error(Faraday::BadRequestError) do |ex|
29
29
  expect(ex.message).to eq('the server responded with status 400')
30
30
  expect(ex.response[:headers]['X-Reason']).to eq('because')
31
31
  expect(ex.response[:status]).to eq(400)
32
32
  end
33
33
  end
34
34
 
35
- it 'raises Faraday::ClientError for 401 responses' do
36
- expect { conn.get('unauthorized') }.to raise_error(Faraday::ClientError) do |ex|
35
+ it 'raises Faraday::UnauthorizedError for 401 responses' do
36
+ expect { conn.get('unauthorized') }.to raise_error(Faraday::UnauthorizedError) do |ex|
37
37
  expect(ex.message).to eq('the server responded with status 401')
38
38
  expect(ex.response[:headers]['X-Reason']).to eq('because')
39
39
  expect(ex.response[:status]).to eq(401)
40
40
  end
41
41
  end
42
42
 
43
- it 'raises Faraday::ClientError for 403 responses' do
44
- expect { conn.get('forbidden') }.to raise_error(Faraday::ClientError) do |ex|
43
+ it 'raises Faraday::ForbiddenError for 403 responses' do
44
+ expect { conn.get('forbidden') }.to raise_error(Faraday::ForbiddenError) do |ex|
45
45
  expect(ex.message).to eq('the server responded with status 403')
46
46
  expect(ex.response[:headers]['X-Reason']).to eq('because')
47
47
  expect(ex.response[:status]).to eq(403)
@@ -56,24 +56,24 @@ RSpec.describe Faraday::Response::RaiseError do
56
56
  end
57
57
  end
58
58
 
59
- it 'raises Faraday::ConnectionFailed for 407 responses' do
60
- expect { conn.get('proxy-error') }.to raise_error(Faraday::ConnectionFailed) do |ex|
61
- expect(ex.message).to eq('407 "Proxy Authentication Required "')
59
+ it 'raises Faraday::ProxyAuthError for 407 responses' do
60
+ expect { conn.get('proxy-error') }.to raise_error(Faraday::ProxyAuthError) do |ex|
61
+ expect(ex.message).to eq('407 "Proxy Authentication Required"')
62
62
  expect(ex.response[:headers]['X-Reason']).to eq('because')
63
63
  expect(ex.response[:status]).to eq(407)
64
64
  end
65
65
  end
66
66
 
67
- it 'raises Faraday::ClientError for 409 responses' do
68
- expect { conn.get('conflict') }.to raise_error(Faraday::ClientError) do |ex|
67
+ it 'raises Faraday::ConflictError for 409 responses' do
68
+ expect { conn.get('conflict') }.to raise_error(Faraday::ConflictError) do |ex|
69
69
  expect(ex.message).to eq('the server responded with status 409')
70
70
  expect(ex.response[:headers]['X-Reason']).to eq('because')
71
71
  expect(ex.response[:status]).to eq(409)
72
72
  end
73
73
  end
74
74
 
75
- it 'raises Faraday::ClientError for 422 responses' do
76
- expect { conn.get('unprocessable-entity') }.to raise_error(Faraday::ClientError) do |ex|
75
+ it 'raises Faraday::UnprocessableEntityError for 422 responses' do
76
+ expect { conn.get('unprocessable-entity') }.to raise_error(Faraday::UnprocessableEntityError) do |ex|
77
77
  expect(ex.message).to eq('the server responded with status 422')
78
78
  expect(ex.response[:headers]['X-Reason']).to eq('because')
79
79
  expect(ex.response[:status]).to eq(422)
@@ -96,8 +96,8 @@ RSpec.describe Faraday::Response::RaiseError do
96
96
  end
97
97
  end
98
98
 
99
- it 'raises Faraday::ClientError for 500 responses' do
100
- expect { conn.get('server-error') }.to raise_error(Faraday::ClientError) do |ex|
99
+ it 'raises Faraday::ServerError for 500 responses' do
100
+ expect { conn.get('server-error') }.to raise_error(Faraday::ServerError) do |ex|
101
101
  expect(ex.message).to eq('the server responded with status 500')
102
102
  expect(ex.response[:headers]['X-Error']).to eq('bailout')
103
103
  expect(ex.response[:status]).to eq(500)
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Faraday::Response do
4
+ subject { Faraday::Response.new(env) }
5
+
6
+ let(:env) do
7
+ Faraday::Env.from(status: 404, body: 'yikes',
8
+ response_headers: { 'Content-Type' => 'text/plain' })
9
+ end
10
+
11
+ it { expect(subject.finished?).to be_truthy }
12
+ it { expect { subject.finish({}) }.to raise_error(RuntimeError) }
13
+ it { expect(subject.success?).to be_falsey }
14
+ it { expect(subject.status).to eq(404) }
15
+ it { expect(subject.body).to eq('yikes') }
16
+ it { expect(subject.headers['Content-Type']).to eq('text/plain') }
17
+ it { expect(subject['content-type']).to eq('text/plain') }
18
+
19
+ describe '#apply_request' do
20
+ before { subject.apply_request(body: 'a=b', method: :post) }
21
+
22
+ it { expect(subject.body).to eq('yikes') }
23
+ it { expect(subject.env[:method]).to eq(:post) }
24
+ end
25
+
26
+ describe '#to_hash' do
27
+ let(:hash) { subject.to_hash }
28
+
29
+ it { expect(hash).to be_a(Hash) }
30
+ it { expect(hash[:status]).to eq(subject.status) }
31
+ it { expect(hash[:response_headers]).to eq(subject.headers) }
32
+ it { expect(hash[:body]).to eq(subject.body) }
33
+ end
34
+
35
+ describe 'marshal serialization support' do
36
+ subject { Faraday::Response.new }
37
+ let(:loaded) { Marshal.load(Marshal.dump(subject)) }
38
+
39
+ before do
40
+ subject.on_complete {}
41
+ subject.finish(env.merge(params: 'moo'))
42
+ end
43
+
44
+ it { expect(loaded.env[:params]).to be_nil }
45
+ it { expect(loaded.env[:body]).to eq(env[:body]) }
46
+ it { expect(loaded.env[:response_headers]).to eq(env[:response_headers]) }
47
+ it { expect(loaded.env[:status]).to eq(env[:status]) }
48
+ end
49
+
50
+ describe '#on_complete' do
51
+ subject { Faraday::Response.new }
52
+
53
+ it 'parse body on finish' do
54
+ subject.on_complete { |env| env[:body] = env[:body].upcase }
55
+ subject.finish(env)
56
+
57
+ expect(subject.body).to eq('YIKES')
58
+ end
59
+
60
+ it 'can access response body in on_complete callback' do
61
+ subject.on_complete { |env| env[:body] = subject.body.upcase }
62
+ subject.finish(env)
63
+
64
+ expect(subject.body).to eq('YIKES')
65
+ end
66
+
67
+ it 'can access response body in on_complete callback' do
68
+ callback_env = nil
69
+ subject.on_complete { |env| callback_env = env }
70
+ subject.finish({})
71
+
72
+ expect(subject.env).to eq(callback_env)
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Faraday::Utils::Headers do
4
+ subject { Faraday::Utils::Headers.new }
5
+
6
+ context 'when Content-Type is set to application/json' do
7
+ before { subject['Content-Type'] = 'application/json' }
8
+
9
+ it { expect(subject.keys).to eq(['Content-Type']) }
10
+ it { expect(subject['Content-Type']).to eq('application/json') }
11
+ it { expect(subject['CONTENT-TYPE']).to eq('application/json') }
12
+ it { expect(subject['content-type']).to eq('application/json') }
13
+ it { is_expected.to include('content-type') }
14
+ end
15
+
16
+ context 'when Content-Type is set to application/xml' do
17
+ before { subject['Content-Type'] = 'application/xml' }
18
+
19
+ it { expect(subject.keys).to eq(['Content-Type']) }
20
+ it { expect(subject['Content-Type']).to eq('application/xml') }
21
+ it { expect(subject['CONTENT-TYPE']).to eq('application/xml') }
22
+ it { expect(subject['content-type']).to eq('application/xml') }
23
+ it { is_expected.to include('content-type') }
24
+ end
25
+
26
+ describe '#fetch' do
27
+ before { subject['Content-Type'] = 'application/json' }
28
+
29
+ it { expect(subject.fetch('Content-Type')).to eq('application/json') }
30
+ it { expect(subject.fetch('CONTENT-TYPE')).to eq('application/json') }
31
+ it { expect(subject.fetch(:content_type)).to eq('application/json') }
32
+ it { expect(subject.fetch('invalid', 'default')).to eq('default') }
33
+ it { expect(subject.fetch('invalid', false)).to eq(false) }
34
+ it { expect(subject.fetch('invalid', nil)).to be_nil }
35
+ it { expect(subject.fetch('Invalid') { |key| "#{key} key" }).to eq('Invalid key') }
36
+ it 'calls a block when provided' do
37
+ block_called = false
38
+ expect(subject.fetch('content-type') { block_called = true }).to eq('application/json')
39
+ expect(block_called).to be_falsey
40
+ end
41
+ it 'raises an error if key not found' do
42
+ expected_error = defined?(KeyError) ? KeyError : IndexError
43
+ expect { subject.fetch('invalid') }.to raise_error(expected_error)
44
+ end
45
+ end
46
+
47
+ describe '#delete' do
48
+ before do
49
+ subject['Content-Type'] = 'application/json'
50
+ @deleted = subject.delete('content-type')
51
+ end
52
+
53
+ it { expect(@deleted).to eq('application/json') }
54
+ it { expect(subject.size).to eq(0) }
55
+ it { is_expected.not_to include('content-type') }
56
+ it { expect(subject.delete('content-type')).to be_nil }
57
+ end
58
+
59
+ describe '#parse' do
60
+ before { subject.parse(headers) }
61
+
62
+ context 'when response headers leave http status line out' do
63
+ let(:headers) { "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n" }
64
+
65
+ it { expect(subject.keys).to eq(%w[Content-Type]) }
66
+ it { expect(subject['Content-Type']).to eq('text/html') }
67
+ it { expect(subject['content-type']).to eq('text/html') }
68
+ end
69
+
70
+ context 'when response headers values include a colon' do
71
+ let(:headers) { "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nLocation: http://sushi.com/\r\n\r\n" }
72
+
73
+ it { expect(subject['location']).to eq('http://sushi.com/') }
74
+ end
75
+
76
+ context 'when response headers include a blank line' do
77
+ let(:headers) { "HTTP/1.1 200 OK\r\n\r\nContent-Type: text/html\r\n\r\n" }
78
+
79
+ it { expect(subject['content-type']).to eq('text/html') }
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Faraday::Utils do
4
+ describe 'headers parsing' do
5
+ let(:multi_response_headers) do
6
+ "HTTP/1.x 500 OK\r\nContent-Type: text/html; charset=UTF-8\r\n" \
7
+ "HTTP/1.x 200 OK\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n"
8
+ end
9
+
10
+ it 'parse headers for aggregated responses' do
11
+ headers = Faraday::Utils::Headers.new
12
+ headers.parse(multi_response_headers)
13
+
14
+ result = headers.to_hash
15
+
16
+ expect(result['Content-Type']).to eq('application/json; charset=UTF-8')
17
+ end
18
+ end
19
+
20
+ describe 'URI parsing' do
21
+ let(:url) { 'http://example.com/abc' }
22
+
23
+ it 'escapes safe buffer' do
24
+ str = FakeSafeBuffer.new('$32,000.00')
25
+ expect(Faraday::Utils.escape(str)).to eq('%2432%2C000.00')
26
+ end
27
+
28
+ it 'parses with default parser' do
29
+ with_default_uri_parser(nil) do
30
+ uri = normalize(url)
31
+ expect(uri.host).to eq('example.com')
32
+ end
33
+ end
34
+
35
+ it 'parses with URI' do
36
+ with_default_uri_parser(::URI) do
37
+ uri = normalize(url)
38
+ expect(uri.host).to eq('example.com')
39
+ end
40
+ end
41
+
42
+ it 'parses with block' do
43
+ with_default_uri_parser(->(u) { "booya#{'!' * u.size}" }) do
44
+ expect(normalize(url)).to eq('booya!!!!!!!!!!!!!!!!!!!!!!')
45
+ end
46
+ end
47
+
48
+ it 'replaces headers hash' do
49
+ headers = Faraday::Utils::Headers.new('authorization' => 't0ps3cr3t!')
50
+ expect(headers).to have_key('authorization')
51
+
52
+ headers.replace('content-type' => 'text/plain')
53
+ expect(headers).not_to have_key('authorization')
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Faraday do
4
+ it 'has a version number' do
5
+ expect(Faraday::VERSION).not_to be nil
6
+ end
7
+
8
+ context 'proxies to default_connection' do
9
+ let(:mock_connection) { double('Connection') }
10
+ before do
11
+ Faraday.default_connection = mock_connection
12
+ end
13
+
14
+ it 'proxies methods that exist on the default_connection' do
15
+ expect(mock_connection).to receive(:this_should_be_proxied)
16
+
17
+ Faraday.this_should_be_proxied
18
+ end
19
+
20
+ it 'uses method_missing on Faraday if there is no proxyable method' do
21
+ expect { Faraday.this_method_does_not_exist }.to raise_error(
22
+ NoMethodError,
23
+ "undefined method `this_method_does_not_exist' for Faraday:Module"
24
+ )
25
+ end
26
+
27
+ it 'proxied methods can be accessed' do
28
+ allow(mock_connection).to receive(:this_should_be_proxied)
29
+
30
+ expect(Faraday.method(:this_should_be_proxied)).to be_a(Method)
31
+ end
32
+
33
+ after do
34
+ Faraday.default_connection = nil
35
+ end
36
+ end
37
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'faraday'
4
- Faraday::Deprecate.skip = false
5
-
6
3
  # This file was generated by the `rspec --init` command. Conventionally, all
7
4
  # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
8
5
  # The generated `.rspec` file contains `--require spec_helper` which will cause
@@ -18,6 +15,29 @@ Faraday::Deprecate.skip = false
18
15
  # it.
19
16
  #
20
17
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
18
+
19
+ require 'simplecov'
20
+ require 'coveralls'
21
+ require 'webmock/rspec'
22
+ WebMock.disable_net_connect!(allow_localhost: true)
23
+
24
+ SimpleCov.formatters = [SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter]
25
+
26
+ SimpleCov.start do
27
+ add_filter '/spec/'
28
+ minimum_coverage 84
29
+ minimum_coverage_by_file 26
30
+ end
31
+
32
+ # Ensure all /lib files are loaded
33
+ # so they will be included in the test coverage report.
34
+ Dir['./lib/**/*.rb'].sort.each { |file| require file }
35
+
36
+ require 'faraday'
37
+ require 'pry'
38
+
39
+ Dir['./spec/support/**/*.rb'].sort.each { |f| require f }
40
+
21
41
  RSpec.configure do |config|
22
42
  # rspec-expectations config goes here. You can use an alternate
23
43
  # assertion/expectation library such as wrong or the stdlib/minitest
@@ -49,57 +69,64 @@ RSpec.configure do |config|
49
69
  # triggering implicit auto-inclusion in groups with matching metadata.
50
70
  config.shared_context_metadata_behavior = :apply_to_host_groups
51
71
 
52
- # Run specs in random order to surface order dependencies. If you find an
53
- # order dependency and want to debug it, you can fix the order by providing
54
- # the seed, which is printed after each run.
55
- # --seed 1234
56
- config.order = :random
57
-
58
- # Seed global randomization in this process using the `--seed` CLI option.
59
- # Setting this allows you to use `--seed` to deterministically reproduce
60
- # test failures related to randomization by passing the same `--seed` value
61
- # as the one that triggered the failure.
62
- Kernel.srand config.seed
63
-
64
- # Limits the available syntax to the non-monkey patched syntax that is
65
- # recommended. For more details, see:
66
- # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
67
- # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
68
- # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
69
- config.disable_monkey_patching!
70
-
71
- # The settings below are suggested to provide a good initial experience
72
- # with RSpec, but feel free to customize to your heart's content.
73
- =begin
74
72
  # This allows you to limit a spec run to individual examples or groups
75
73
  # you care about by tagging them with `:focus` metadata. When nothing
76
74
  # is tagged with `:focus`, all examples get run. RSpec also provides
77
75
  # aliases for `it`, `describe`, and `context` that include `:focus`
78
76
  # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
79
- config.filter_run_when_matching :focus
77
+ # config.filter_run_when_matching :focus
80
78
 
81
79
  # Allows RSpec to persist some state between runs in order to support
82
80
  # the `--only-failures` and `--next-failure` CLI options. We recommend
83
81
  # you configure your source control system to ignore this file.
84
- config.example_status_persistence_file_path = "spec/examples.txt"
82
+ # config.example_status_persistence_file_path = "spec/examples.txt"
83
+
84
+ # Limits the available syntax to the non-monkey patched syntax that is
85
+ # recommended. For more details, see:
86
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
87
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
88
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
89
+ # config.disable_monkey_patching!
85
90
 
86
91
  # This setting enables warnings. It's recommended, but in some cases may
87
92
  # be too noisy due to issues in dependencies.
88
- config.warnings = true
93
+ # config.warnings = true
89
94
 
90
95
  # Many RSpec users commonly either run the entire suite or an individual
91
96
  # file, and it's useful to allow more verbose output when running an
92
97
  # individual spec file.
93
- if config.files_to_run.one?
94
- # Use the documentation formatter for detailed output,
95
- # unless a formatter has already been configured
96
- # (e.g. via a command-line flag).
97
- config.default_formatter = "doc"
98
- end
98
+ # if config.files_to_run.one?
99
+ # # Use the documentation formatter for detailed output,
100
+ # # unless a formatter has already been configured
101
+ # # (e.g. via a command-line flag).
102
+ # config.default_formatter = "doc"
103
+ # end
99
104
 
100
105
  # Print the 10 slowest examples and example groups at the
101
106
  # end of the spec run, to help surface which specs are running
102
107
  # particularly slow.
103
- config.profile_examples = 10
104
- =end
108
+ # config.profile_examples = 10
109
+
110
+ # Run specs in random order to surface order dependencies. If you find an
111
+ # order dependency and want to debug it, you can fix the order by providing
112
+ # the seed, which is printed after each run.
113
+ # --seed 1234
114
+ config.order = :random
115
+
116
+ # Seed global randomization in this process using the `--seed` CLI option.
117
+ # Setting this allows you to use `--seed` to deterministically reproduce
118
+ # test failures related to randomization by passing the same `--seed` value
119
+ # as the one that triggered the failure.
120
+ Kernel.srand config.seed
121
+
122
+ config.include Faraday::HelperMethods
123
+ end
124
+
125
+ # Extends RSpec DocumentationFormatter to hide skipped tests.
126
+ module FormatterOverrides
127
+ def example_pending(_arg); end
128
+
129
+ def dump_pending(_arg); end
130
+
131
+ RSpec::Core::Formatters::DocumentationFormatter.prepend self
105
132
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Allows to disable WebMock stubs
4
+ module DisablingStub
5
+ def disable
6
+ @disabled = true
7
+ end
8
+
9
+ def disabled?
10
+ @disabled
11
+ end
12
+
13
+ WebMock::RequestStub.prepend self
14
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # emulates ActiveSupport::SafeBuffer#gsub
4
+ FakeSafeBuffer = Struct.new(:string) do
5
+ def to_s
6
+ self
7
+ end
8
+
9
+ def gsub(regex)
10
+ string.gsub(regex) do
11
+ match, = $&, '' =~ /a/
12
+ yield(match)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'multipart_parser/reader'
4
+
5
+ module Faraday
6
+ module HelperMethods
7
+ def self.included(base)
8
+ base.extend ClassMethods
9
+ end
10
+
11
+ module ClassMethods
12
+ def features(*features)
13
+ @features = features
14
+ end
15
+
16
+ def on_feature(name)
17
+ yield if block_given? && feature?(name)
18
+ end
19
+
20
+ def feature?(name)
21
+ if @features.nil?
22
+ superclass.feature?(name) if superclass.respond_to?(:feature?)
23
+ elsif @features.include?(name)
24
+ true
25
+ end
26
+ end
27
+
28
+ def method_with_body?(method)
29
+ METHODS_WITH_BODY.include?(method.to_s)
30
+ end
31
+ end
32
+
33
+ def ssl_mode?
34
+ ENV['SSL'] == 'yes'
35
+ end
36
+
37
+ def normalize(url)
38
+ Faraday::Utils::URI(url)
39
+ end
40
+
41
+ def with_default_uri_parser(parser)
42
+ old_parser = Faraday::Utils.default_uri_parser
43
+ begin
44
+ Faraday::Utils.default_uri_parser = parser
45
+ yield
46
+ ensure
47
+ Faraday::Utils.default_uri_parser = old_parser
48
+ end
49
+ end
50
+
51
+ def with_env(new_env)
52
+ old_env = {}
53
+
54
+ new_env.each do |key, value|
55
+ old_env[key] = ENV.fetch(key, false)
56
+ ENV[key] = value
57
+ end
58
+
59
+ begin
60
+ yield
61
+ ensure
62
+ old_env.each do |key, value|
63
+ value == false ? ENV.delete(key) : ENV[key] = value
64
+ end
65
+ end
66
+ end
67
+
68
+ def with_env_proxy_disabled
69
+ Faraday.ignore_env_proxy = true
70
+
71
+ begin
72
+ yield
73
+ ensure
74
+ Faraday.ignore_env_proxy = false
75
+ end
76
+ end
77
+
78
+ def capture_warnings
79
+ old = $stderr
80
+ $stderr = StringIO.new
81
+ begin
82
+ yield
83
+ $stderr.string
84
+ ensure
85
+ $stderr = old
86
+ end
87
+ end
88
+
89
+ def multipart_file
90
+ Faraday::FilePart.new(__FILE__, 'text/x-ruby')
91
+ end
92
+
93
+ # parse boundary out of a Content-Type header like:
94
+ # Content-Type: multipart/form-data; boundary=gc0p4Jq0M2Yt08jU534c0p
95
+ def parse_multipart_boundary(ctype)
96
+ MultipartParser::Reader.extract_boundary_value(ctype)
97
+ end
98
+
99
+ # parse a multipart MIME message, returning a hash of any multipart errors
100
+ def parse_multipart(boundary, body)
101
+ reader = MultipartParser::Reader.new(boundary)
102
+ result = { errors: [], parts: [] }
103
+ def result.part(name)
104
+ hash = self[:parts].detect { |h| h[:part].name == name }
105
+ [hash[:part], hash[:body].join]
106
+ end
107
+
108
+ reader.on_part do |part|
109
+ result[:parts] << thispart = {
110
+ part: part,
111
+ body: []
112
+ }
113
+ part.on_data do |chunk|
114
+ thispart[:body] << chunk
115
+ end
116
+ end
117
+ reader.on_error do |msg|
118
+ result[:errors] << msg
119
+ end
120
+ reader.write(body)
121
+ result
122
+ end
123
+
124
+ def method_with_body?(method)
125
+ self.class.method_with_body?(method)
126
+ end
127
+
128
+ def big_string
129
+ kb = 1024
130
+ (32..126).map(&:chr).cycle.take(50 * kb).join
131
+ end
132
+ end
133
+ end