faraday 0.13.0 → 2.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +496 -0
- data/LICENSE.md +1 -1
- data/README.md +28 -328
- data/Rakefile +7 -0
- data/examples/client_spec.rb +97 -0
- data/examples/client_test.rb +118 -0
- data/lib/faraday/adapter/test.rb +127 -68
- data/lib/faraday/adapter.rb +71 -22
- data/lib/faraday/adapter_registry.rb +30 -0
- data/lib/faraday/connection.rb +314 -226
- data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
- data/lib/faraday/encoders/nested_params_encoder.rb +176 -0
- data/lib/faraday/error.rb +121 -37
- data/lib/faraday/logging/formatter.rb +106 -0
- data/lib/faraday/methods.rb +6 -0
- data/lib/faraday/middleware.rb +18 -25
- data/lib/faraday/middleware_registry.rb +65 -0
- data/lib/faraday/options/connection_options.rb +22 -0
- data/lib/faraday/options/env.rb +181 -0
- data/lib/faraday/options/proxy_options.rb +32 -0
- data/lib/faraday/options/request_options.rb +22 -0
- data/lib/faraday/options/ssl_options.rb +59 -0
- data/lib/faraday/options.rb +41 -195
- data/lib/faraday/parameters.rb +4 -196
- data/lib/faraday/rack_builder.rb +91 -74
- data/lib/faraday/request/authorization.rb +37 -29
- data/lib/faraday/request/instrumentation.rb +47 -27
- data/lib/faraday/request/json.rb +55 -0
- data/lib/faraday/request/url_encoded.rb +45 -23
- data/lib/faraday/request.rb +74 -32
- data/lib/faraday/response/json.rb +54 -0
- data/lib/faraday/response/logger.rb +22 -69
- data/lib/faraday/response/raise_error.rb +57 -14
- data/lib/faraday/response.rb +26 -33
- data/lib/faraday/utils/headers.rb +139 -0
- data/lib/faraday/utils/params_hash.rb +61 -0
- data/lib/faraday/utils.rb +47 -251
- data/lib/faraday/version.rb +5 -0
- data/lib/faraday.rb +104 -197
- data/spec/external_adapters/faraday_specs_setup.rb +14 -0
- data/spec/faraday/adapter/test_spec.rb +377 -0
- data/spec/faraday/adapter_registry_spec.rb +28 -0
- data/spec/faraday/adapter_spec.rb +55 -0
- data/spec/faraday/connection_spec.rb +787 -0
- data/spec/faraday/error_spec.rb +60 -0
- data/spec/faraday/middleware_spec.rb +52 -0
- data/spec/faraday/options/env_spec.rb +70 -0
- data/spec/faraday/options/options_spec.rb +297 -0
- data/spec/faraday/options/proxy_options_spec.rb +44 -0
- data/spec/faraday/options/request_options_spec.rb +19 -0
- data/spec/faraday/params_encoders/flat_spec.rb +42 -0
- data/spec/faraday/params_encoders/nested_spec.rb +142 -0
- data/spec/faraday/rack_builder_spec.rb +302 -0
- data/spec/faraday/request/authorization_spec.rb +83 -0
- data/spec/faraday/request/instrumentation_spec.rb +74 -0
- data/spec/faraday/request/json_spec.rb +111 -0
- data/spec/faraday/request/url_encoded_spec.rb +82 -0
- data/spec/faraday/request_spec.rb +109 -0
- data/spec/faraday/response/json_spec.rb +117 -0
- data/spec/faraday/response/logger_spec.rb +220 -0
- data/spec/faraday/response/raise_error_spec.rb +172 -0
- data/spec/faraday/response_spec.rb +75 -0
- data/spec/faraday/utils/headers_spec.rb +82 -0
- data/spec/faraday/utils_spec.rb +117 -0
- data/spec/faraday_spec.rb +37 -0
- data/spec/spec_helper.rb +132 -0
- data/spec/support/disabling_stub.rb +14 -0
- data/spec/support/fake_safe_buffer.rb +15 -0
- data/spec/support/helper_methods.rb +96 -0
- data/spec/support/shared_examples/adapter.rb +104 -0
- data/spec/support/shared_examples/params_encoder.rb +18 -0
- data/spec/support/shared_examples/request_method.rb +249 -0
- data/spec/support/streaming_response_checker.rb +35 -0
- metadata +71 -34
- data/lib/faraday/adapter/em_http.rb +0 -243
- data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -56
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -66
- data/lib/faraday/adapter/em_synchrony.rb +0 -106
- data/lib/faraday/adapter/excon.rb +0 -80
- data/lib/faraday/adapter/httpclient.rb +0 -128
- data/lib/faraday/adapter/net_http.rb +0 -135
- data/lib/faraday/adapter/net_http_persistent.rb +0 -54
- data/lib/faraday/adapter/patron.rb +0 -83
- data/lib/faraday/adapter/rack.rb +0 -58
- data/lib/faraday/adapter/typhoeus.rb +0 -123
- data/lib/faraday/autoload.rb +0 -84
- data/lib/faraday/request/basic_authentication.rb +0 -13
- data/lib/faraday/request/multipart.rb +0 -68
- data/lib/faraday/request/retry.rb +0 -164
- data/lib/faraday/request/token_authentication.rb +0 -15
- data/lib/faraday/upload_io.rb +0 -67
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Faraday::ClientError do
|
4
|
+
describe '.initialize' do
|
5
|
+
subject { described_class.new(exception, response) }
|
6
|
+
let(:response) { nil }
|
7
|
+
|
8
|
+
context 'with exception only' do
|
9
|
+
let(:exception) { RuntimeError.new('test') }
|
10
|
+
|
11
|
+
it { expect(subject.wrapped_exception).to eq(exception) }
|
12
|
+
it { expect(subject.response).to be_nil }
|
13
|
+
it { expect(subject.message).to eq(exception.message) }
|
14
|
+
it { expect(subject.backtrace).to eq(exception.backtrace) }
|
15
|
+
it { expect(subject.inspect).to eq('#<Faraday::ClientError wrapped=#<RuntimeError: test>>') }
|
16
|
+
it { expect(subject.response_status).to be_nil }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'with response hash' do
|
20
|
+
let(:exception) { { status: 400 } }
|
21
|
+
|
22
|
+
it { expect(subject.wrapped_exception).to be_nil }
|
23
|
+
it { expect(subject.response).to eq(exception) }
|
24
|
+
it { expect(subject.message).to eq('the server responded with status 400') }
|
25
|
+
it { expect(subject.inspect).to eq('#<Faraday::ClientError response={:status=>400}>') }
|
26
|
+
it { expect(subject.response_status).to eq(400) }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'with string' do
|
30
|
+
let(:exception) { 'custom message' }
|
31
|
+
|
32
|
+
it { expect(subject.wrapped_exception).to be_nil }
|
33
|
+
it { expect(subject.response).to be_nil }
|
34
|
+
it { expect(subject.message).to eq('custom message') }
|
35
|
+
it { expect(subject.inspect).to eq('#<Faraday::ClientError #<Faraday::ClientError: custom message>>') }
|
36
|
+
it { expect(subject.response_status).to be_nil }
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with anything else #to_s' do
|
40
|
+
let(:exception) { %w[error1 error2] }
|
41
|
+
|
42
|
+
it { expect(subject.wrapped_exception).to be_nil }
|
43
|
+
it { expect(subject.response).to be_nil }
|
44
|
+
it { expect(subject.message).to eq('["error1", "error2"]') }
|
45
|
+
it { expect(subject.inspect).to eq('#<Faraday::ClientError #<Faraday::ClientError: ["error1", "error2"]>>') }
|
46
|
+
it { expect(subject.response_status).to be_nil }
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'with exception string and response hash' do
|
50
|
+
let(:exception) { 'custom message' }
|
51
|
+
let(:response) { { status: 400 } }
|
52
|
+
|
53
|
+
it { expect(subject.wrapped_exception).to be_nil }
|
54
|
+
it { expect(subject.response).to eq(response) }
|
55
|
+
it { expect(subject.message).to eq('custom message') }
|
56
|
+
it { expect(subject.inspect).to eq('#<Faraday::ClientError response={:status=>400}>') }
|
57
|
+
it { expect(subject.response_status).to eq(400) }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Faraday::Middleware do
|
4
|
+
subject { described_class.new(app) }
|
5
|
+
let(:app) { double }
|
6
|
+
|
7
|
+
describe 'options' do
|
8
|
+
context 'when options are passed to the middleware' do
|
9
|
+
subject { described_class.new(app, options) }
|
10
|
+
let(:options) { { field: 'value' } }
|
11
|
+
|
12
|
+
it 'accepts options when initialized' do
|
13
|
+
expect(subject.options[:field]).to eq('value')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#on_request' do
|
19
|
+
subject do
|
20
|
+
Class.new(described_class) do
|
21
|
+
def on_request(env)
|
22
|
+
# do nothing
|
23
|
+
end
|
24
|
+
end.new(app)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'is called by #call' do
|
28
|
+
expect(app).to receive(:call).and_return(app)
|
29
|
+
expect(app).to receive(:on_complete)
|
30
|
+
is_expected.to receive(:call).and_call_original
|
31
|
+
is_expected.to receive(:on_request)
|
32
|
+
subject.call(double)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#close' do
|
37
|
+
context "with app that doesn't support \#close" do
|
38
|
+
it 'should issue warning' do
|
39
|
+
is_expected.to receive(:warn)
|
40
|
+
subject.close
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "with app that supports \#close" do
|
45
|
+
it 'should issue warning' do
|
46
|
+
expect(app).to receive(:close)
|
47
|
+
is_expected.to_not receive(:warn)
|
48
|
+
subject.close
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Faraday::Env do
|
4
|
+
subject(:env) { described_class.new }
|
5
|
+
|
6
|
+
it 'allows to access members' do
|
7
|
+
expect(env.method).to be_nil
|
8
|
+
env.method = :get
|
9
|
+
expect(env.method).to eq(:get)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'allows to access symbol non members' do
|
13
|
+
expect(env[:custom]).to be_nil
|
14
|
+
env[:custom] = :boom
|
15
|
+
expect(env[:custom]).to eq(:boom)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'allows to access string non members' do
|
19
|
+
expect(env['custom']).to be_nil
|
20
|
+
env['custom'] = :boom
|
21
|
+
expect(env['custom']).to eq(:boom)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'ignores false when fetching' do
|
25
|
+
ssl = Faraday::SSLOptions.new
|
26
|
+
ssl.verify = false
|
27
|
+
expect(ssl.fetch(:verify, true)).to be_falsey
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'retains custom members' do
|
31
|
+
env[:foo] = 'custom 1'
|
32
|
+
env[:bar] = :custom2
|
33
|
+
env2 = Faraday::Env.from(env)
|
34
|
+
env2[:baz] = 'custom 3'
|
35
|
+
|
36
|
+
expect(env2[:foo]).to eq('custom 1')
|
37
|
+
expect(env2[:bar]).to eq(:custom2)
|
38
|
+
expect(env[:baz]).to be_nil
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#body' do
|
42
|
+
subject(:env) { described_class.from(body: { foo: 'bar' }) }
|
43
|
+
|
44
|
+
context 'when response is not finished yet' do
|
45
|
+
it 'returns the request body' do
|
46
|
+
expect(env.body).to eq(foo: 'bar')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when response is finished' do
|
51
|
+
before do
|
52
|
+
env.status = 200
|
53
|
+
env.body = { bar: 'foo' }
|
54
|
+
env.response = Faraday::Response.new(env)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'returns the response body' do
|
58
|
+
expect(env.body).to eq(bar: 'foo')
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'allows to access request_body' do
|
62
|
+
expect(env.request_body).to eq(foo: 'bar')
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'allows to access response_body' do
|
66
|
+
expect(env.response_body).to eq(bar: 'foo')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,297 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Faraday::Options do
|
4
|
+
SubOptions = Class.new(Faraday::Options.new(:sub_a, :sub_b))
|
5
|
+
class ParentOptions < Faraday::Options.new(:a, :b, :c)
|
6
|
+
options c: SubOptions
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#merge' do
|
10
|
+
it 'merges options with hashes' do
|
11
|
+
options = ParentOptions.new(1)
|
12
|
+
expect(options.a).to eq(1)
|
13
|
+
expect(options.b).to be_nil
|
14
|
+
|
15
|
+
dup = options.merge a: 2, b: 3
|
16
|
+
expect(dup.a).to eq(2)
|
17
|
+
expect(dup.b).to eq(3)
|
18
|
+
expect(options.a).to eq(1)
|
19
|
+
expect(options.b).to be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'deeply merges two options' do
|
23
|
+
sub_opts1 = SubOptions.from(sub_a: 3)
|
24
|
+
sub_opts2 = SubOptions.from(sub_b: 4)
|
25
|
+
opt1 = ParentOptions.from(a: 1, c: sub_opts1)
|
26
|
+
opt2 = ParentOptions.from(b: 2, c: sub_opts2)
|
27
|
+
|
28
|
+
merged = opt1.merge(opt2)
|
29
|
+
|
30
|
+
expected_sub_opts = SubOptions.from(sub_a: 3, sub_b: 4)
|
31
|
+
expected = ParentOptions.from(a: 1, b: 2, c: expected_sub_opts)
|
32
|
+
expect(merged).to eq(expected)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'deeply merges options with hashes' do
|
36
|
+
sub_opts1 = SubOptions.from(sub_a: 3)
|
37
|
+
sub_opts2 = { sub_b: 4 }
|
38
|
+
opt1 = ParentOptions.from(a: 1, c: sub_opts1)
|
39
|
+
opt2 = { b: 2, c: sub_opts2 }
|
40
|
+
|
41
|
+
merged = opt1.merge(opt2)
|
42
|
+
|
43
|
+
expected_sub_opts = SubOptions.from(sub_a: 3, sub_b: 4)
|
44
|
+
expected = ParentOptions.from(a: 1, b: 2, c: expected_sub_opts)
|
45
|
+
expect(merged).to eq(expected)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'deeply merges options with nil' do
|
49
|
+
sub_opts = SubOptions.new(3, 4)
|
50
|
+
options = ParentOptions.new(1, 2, sub_opts)
|
51
|
+
expect(options.a).to eq(1)
|
52
|
+
expect(options.b).to eq(2)
|
53
|
+
expect(options.c.sub_a).to eq(3)
|
54
|
+
expect(options.c.sub_b).to eq(4)
|
55
|
+
|
56
|
+
options2 = ParentOptions.from(b: 5, c: nil)
|
57
|
+
|
58
|
+
merged = options.merge(options2)
|
59
|
+
|
60
|
+
expect(merged.b).to eq(5)
|
61
|
+
expect(merged.c).to eq(sub_opts)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'deeply merges options with options having nil sub-options' do
|
65
|
+
options = ParentOptions.from(a: 1)
|
66
|
+
|
67
|
+
sub_opts = SubOptions.new(3, 4)
|
68
|
+
options2 = ParentOptions.from(b: 2, c: sub_opts)
|
69
|
+
|
70
|
+
expect(options.a).to eq(1)
|
71
|
+
expect(options2.b).to eq(2)
|
72
|
+
expect(options2.c.sub_a).to eq(3)
|
73
|
+
expect(options2.c.sub_b).to eq(4)
|
74
|
+
|
75
|
+
merged = options.merge(options2)
|
76
|
+
|
77
|
+
expect(merged.c).to eq(sub_opts)
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#dup' do
|
81
|
+
it 'duplicate options but not sub-options' do
|
82
|
+
sub_opts = SubOptions.from(sub_a: 3)
|
83
|
+
opts = ParentOptions.from(b: 1, c: sub_opts)
|
84
|
+
|
85
|
+
duped = opts.dup
|
86
|
+
duped.b = 2
|
87
|
+
duped.c.sub_a = 4
|
88
|
+
|
89
|
+
expect(opts.b).to eq(1)
|
90
|
+
expect(opts.c.sub_a).to eq(4)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#deep_dup' do
|
95
|
+
it 'duplicate options and also suboptions' do
|
96
|
+
sub_opts = SubOptions.from(sub_a: 3)
|
97
|
+
opts = ParentOptions.from(b: 1, c: sub_opts)
|
98
|
+
|
99
|
+
duped = opts.deep_dup
|
100
|
+
duped.b = 2
|
101
|
+
duped.c.sub_a = 4
|
102
|
+
|
103
|
+
expect(opts.b).to eq(1)
|
104
|
+
expect(opts.c.sub_a).to eq(3)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '#clear' do
|
109
|
+
it 'clears the options' do
|
110
|
+
options = SubOptions.new(1)
|
111
|
+
expect(options.empty?).not_to be_truthy
|
112
|
+
options.clear
|
113
|
+
expect(options.empty?).to be_truthy
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '#empty?' do
|
118
|
+
it 'returns true only if all options are nil' do
|
119
|
+
options = SubOptions.new
|
120
|
+
expect(options.empty?).to be_truthy
|
121
|
+
options.sub_a = 1
|
122
|
+
expect(options.empty?).not_to be_truthy
|
123
|
+
options.delete(:sub_a)
|
124
|
+
expect(options.empty?).to be_truthy
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe '#each_key' do
|
129
|
+
it 'allows to iterate through keys' do
|
130
|
+
options = ParentOptions.new(1, 2, 3)
|
131
|
+
enum = options.each_key
|
132
|
+
expect(enum.next.to_sym).to eq(:a)
|
133
|
+
expect(enum.next.to_sym).to eq(:b)
|
134
|
+
expect(enum.next.to_sym).to eq(:c)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe '#key?' do
|
139
|
+
it 'returns true if the key exists and is not nil' do
|
140
|
+
options = SubOptions.new
|
141
|
+
expect(options.key?(:sub_a)).not_to be_truthy
|
142
|
+
options.sub_a = 1
|
143
|
+
expect(options.key?(:sub_a)).to be_truthy
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe '#each_value' do
|
148
|
+
it 'allows to iterate through values' do
|
149
|
+
options = ParentOptions.new(1, 2, 3)
|
150
|
+
enum = options.each_value
|
151
|
+
expect(enum.next).to eq(1)
|
152
|
+
expect(enum.next).to eq(2)
|
153
|
+
expect(enum.next).to eq(3)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe '#value?' do
|
158
|
+
it 'returns true if any key has that value' do
|
159
|
+
options = SubOptions.new
|
160
|
+
expect(options.value?(1)).not_to be_truthy
|
161
|
+
options.sub_a = 1
|
162
|
+
expect(options.value?(1)).to be_truthy
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe '#update' do
|
167
|
+
it 'updates options from hashes' do
|
168
|
+
options = ParentOptions.new(1)
|
169
|
+
expect(options.a).to eq(1)
|
170
|
+
expect(options.b).to be_nil
|
171
|
+
|
172
|
+
updated = options.update a: 2, b: 3
|
173
|
+
expect(options.a).to eq(2)
|
174
|
+
expect(options.b).to eq(3)
|
175
|
+
expect(updated).to eq(options)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe '#delete' do
|
180
|
+
it 'allows to remove value for key' do
|
181
|
+
options = ParentOptions.new(1)
|
182
|
+
expect(options.a).to eq(1)
|
183
|
+
expect(options.delete(:a)).to eq(1)
|
184
|
+
expect(options.a).to be_nil
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe '#from' do
|
189
|
+
it { expect { ParentOptions.from invalid: 1 }.to raise_error(NoMethodError) }
|
190
|
+
|
191
|
+
it 'works with options' do
|
192
|
+
options = ParentOptions.new(1)
|
193
|
+
|
194
|
+
value = ParentOptions.from(options)
|
195
|
+
expect(value.a).to eq(1)
|
196
|
+
expect(value.b).to be_nil
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'works with options with sub object' do
|
200
|
+
sub = SubOptions.new(1)
|
201
|
+
options = ParentOptions.from a: 1, c: sub
|
202
|
+
expect(options).to be_a_kind_of(ParentOptions)
|
203
|
+
expect(options.a).to eq(1)
|
204
|
+
expect(options.b).to be_nil
|
205
|
+
expect(options.c).to be_a_kind_of(SubOptions)
|
206
|
+
expect(options.c.sub_a).to eq(1)
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'works with hash' do
|
210
|
+
options = ParentOptions.from a: 1
|
211
|
+
expect(options).to be_a_kind_of(ParentOptions)
|
212
|
+
expect(options.a).to eq(1)
|
213
|
+
expect(options.b).to be_nil
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'works with hash with sub object' do
|
217
|
+
options = ParentOptions.from a: 1, c: { sub_a: 1 }
|
218
|
+
expect(options).to be_a_kind_of(ParentOptions)
|
219
|
+
expect(options.a).to eq(1)
|
220
|
+
expect(options.b).to be_nil
|
221
|
+
expect(options.c).to be_a_kind_of(SubOptions)
|
222
|
+
expect(options.c.sub_a).to eq(1)
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'works with deep hash' do
|
226
|
+
hash = { b: 1 }
|
227
|
+
options = ParentOptions.from a: hash
|
228
|
+
expect(options.a[:b]).to eq(1)
|
229
|
+
|
230
|
+
hash[:b] = 2
|
231
|
+
expect(options.a[:b]).to eq(1)
|
232
|
+
|
233
|
+
options.a[:b] = 3
|
234
|
+
expect(hash[:b]).to eq(2)
|
235
|
+
expect(options.a[:b]).to eq(3)
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'works with nil' do
|
239
|
+
options = ParentOptions.from(nil)
|
240
|
+
expect(options).to be_a_kind_of(ParentOptions)
|
241
|
+
expect(options.a).to be_nil
|
242
|
+
expect(options.b).to be_nil
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'respects inheritance' do
|
246
|
+
subclass = Class.new(ParentOptions)
|
247
|
+
options = subclass.from(c: { sub_a: 'hello' })
|
248
|
+
expect(options.c).to be_a_kind_of(SubOptions)
|
249
|
+
expect(options.c.sub_a).to eq('hello')
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
describe '#memoized' do
|
254
|
+
subject(:options_class) { Class.new(ParentOptions) }
|
255
|
+
it 'requires block' do
|
256
|
+
expect { options_class.memoized(:a) }.to raise_error(ArgumentError)
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'accepts block' do
|
260
|
+
options_class.memoized(:a) { :foo }
|
261
|
+
expect(options_class.new.a).to eql(:foo)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
describe '#fetch' do
|
266
|
+
subject { SubOptions.new }
|
267
|
+
|
268
|
+
context 'when the fetched key has no value' do
|
269
|
+
it 'uses falsey default' do
|
270
|
+
expect(subject.fetch(:sub_a, false) { |_| :blah }).to be_falsey
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'accepts block' do
|
274
|
+
expect(subject.fetch(:sub_a) { |k| "yo #{k.inspect}" }).to eq('yo :sub_a')
|
275
|
+
end
|
276
|
+
|
277
|
+
it 'needs a default if key is missing' do
|
278
|
+
expect { subject.fetch(:sub_a) }.to raise_error(Faraday::Options.fetch_error_class)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
context 'when the fetched key has a value' do
|
283
|
+
before do
|
284
|
+
subject.sub_a = 1
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'grabs value' do
|
288
|
+
expect(subject.fetch(:sub_a, false) { |_| :blah }).to eq(1)
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'works with key' do
|
292
|
+
expect(subject.fetch(:sub_a)).to eq(1)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Faraday::ProxyOptions do
|
4
|
+
describe '#from' do
|
5
|
+
it 'works with string' do
|
6
|
+
options = Faraday::ProxyOptions.from 'http://user:pass@example.org'
|
7
|
+
expect(options.user).to eq('user')
|
8
|
+
expect(options.password).to eq('pass')
|
9
|
+
expect(options.uri).to be_a_kind_of(URI)
|
10
|
+
expect(options.path).to eq('')
|
11
|
+
expect(options.port).to eq(80)
|
12
|
+
expect(options.host).to eq('example.org')
|
13
|
+
expect(options.scheme).to eq('http')
|
14
|
+
expect(options.inspect).to match('#<Faraday::ProxyOptions uri=')
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'defaults to http' do
|
18
|
+
options = Faraday::ProxyOptions.from 'example.org'
|
19
|
+
expect(options.port).to eq(80)
|
20
|
+
expect(options.host).to eq('example.org')
|
21
|
+
expect(options.scheme).to eq('http')
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'works with nil' do
|
25
|
+
options = Faraday::ProxyOptions.from nil
|
26
|
+
expect(options).to be_a_kind_of(Faraday::ProxyOptions)
|
27
|
+
expect(options.inspect).to eq('#<Faraday::ProxyOptions (empty)>')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'works with no auth' do
|
31
|
+
proxy = Faraday::ProxyOptions.from 'http://example.org'
|
32
|
+
expect(proxy.user).to be_nil
|
33
|
+
expect(proxy.password).to be_nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'allows hash access' do
|
38
|
+
proxy = Faraday::ProxyOptions.from 'http://a%40b:pw%20d@example.org'
|
39
|
+
expect(proxy.user).to eq('a@b')
|
40
|
+
expect(proxy[:user]).to eq('a@b')
|
41
|
+
expect(proxy.password).to eq('pw d')
|
42
|
+
expect(proxy[:password]).to eq('pw d')
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Faraday::RequestOptions do
|
4
|
+
subject(:options) { Faraday::RequestOptions.new }
|
5
|
+
|
6
|
+
it 'allows to set the request proxy' do
|
7
|
+
expect(options.proxy).to be_nil
|
8
|
+
|
9
|
+
expect { options[:proxy] = { booya: 1 } }.to raise_error(NoMethodError)
|
10
|
+
|
11
|
+
options[:proxy] = { user: 'user' }
|
12
|
+
expect(options.proxy).to be_a_kind_of(Faraday::ProxyOptions)
|
13
|
+
expect(options.proxy.user).to eq('user')
|
14
|
+
|
15
|
+
options.proxy = nil
|
16
|
+
expect(options.proxy).to be_nil
|
17
|
+
expect(options.inspect).to eq('#<Faraday::RequestOptions (empty)>')
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rack/utils'
|
4
|
+
|
5
|
+
RSpec.describe Faraday::FlatParamsEncoder do
|
6
|
+
it_behaves_like 'a params encoder'
|
7
|
+
|
8
|
+
it 'decodes arrays' do
|
9
|
+
query = 'a=one&a=two&a=three'
|
10
|
+
expected = { 'a' => %w[one two three] }
|
11
|
+
expect(subject.decode(query)).to eq(expected)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'decodes boolean values' do
|
15
|
+
query = 'a=true&b=false'
|
16
|
+
expected = { 'a' => 'true', 'b' => 'false' }
|
17
|
+
expect(subject.decode(query)).to eq(expected)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'encodes boolean values' do
|
21
|
+
params = { a: true, b: false }
|
22
|
+
expect(subject.encode(params)).to eq('a=true&b=false')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'encodes boolean values in array' do
|
26
|
+
params = { a: [true, false] }
|
27
|
+
expect(subject.encode(params)).to eq('a=true&a=false')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'encodes empty array in hash' do
|
31
|
+
params = { a: [] }
|
32
|
+
expect(subject.encode(params)).to eq('a=')
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'encodes unsorted when asked' do
|
36
|
+
params = { b: false, a: true }
|
37
|
+
expect(subject.encode(params)).to eq('a=true&b=false')
|
38
|
+
Faraday::FlatParamsEncoder.sort_params = false
|
39
|
+
expect(subject.encode(params)).to eq('b=false&a=true')
|
40
|
+
Faraday::FlatParamsEncoder.sort_params = true
|
41
|
+
end
|
42
|
+
end
|