http 5.3.1 → 6.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 +4 -4
- data/CHANGELOG.md +241 -41
- data/LICENSE.txt +1 -1
- data/README.md +110 -13
- data/UPGRADING.md +491 -0
- data/http.gemspec +32 -29
- data/lib/http/base64.rb +11 -1
- data/lib/http/chainable/helpers.rb +62 -0
- data/lib/http/chainable/verbs.rb +136 -0
- data/lib/http/chainable.rb +232 -136
- data/lib/http/client.rb +158 -127
- data/lib/http/connection/internals.rb +141 -0
- data/lib/http/connection.rb +126 -97
- data/lib/http/content_type.rb +61 -6
- data/lib/http/errors.rb +25 -1
- data/lib/http/feature.rb +65 -5
- data/lib/http/features/auto_deflate.rb +124 -17
- data/lib/http/features/auto_inflate.rb +38 -15
- data/lib/http/features/caching/entry.rb +178 -0
- data/lib/http/features/caching/in_memory_store.rb +63 -0
- data/lib/http/features/caching.rb +216 -0
- data/lib/http/features/digest_auth.rb +234 -0
- data/lib/http/features/instrumentation.rb +97 -17
- data/lib/http/features/logging.rb +183 -5
- data/lib/http/features/normalize_uri.rb +17 -0
- data/lib/http/features/raise_error.rb +18 -3
- data/lib/http/form_data/composite_io.rb +106 -0
- data/lib/http/form_data/file.rb +95 -0
- data/lib/http/form_data/multipart/param.rb +62 -0
- data/lib/http/form_data/multipart.rb +106 -0
- data/lib/http/form_data/part.rb +52 -0
- data/lib/http/form_data/readable.rb +58 -0
- data/lib/http/form_data/urlencoded.rb +175 -0
- data/lib/http/form_data/version.rb +8 -0
- data/lib/http/form_data.rb +102 -0
- data/lib/http/headers/known.rb +3 -0
- data/lib/http/headers/normalizer.rb +17 -36
- data/lib/http/headers.rb +172 -65
- data/lib/http/mime_type/adapter.rb +24 -9
- data/lib/http/mime_type/json.rb +19 -4
- data/lib/http/mime_type.rb +21 -3
- data/lib/http/options/definitions.rb +189 -0
- data/lib/http/options.rb +172 -125
- data/lib/http/redirector.rb +80 -75
- data/lib/http/request/body.rb +87 -6
- data/lib/http/request/builder.rb +184 -0
- data/lib/http/request/proxy.rb +83 -0
- data/lib/http/request/writer.rb +76 -16
- data/lib/http/request.rb +214 -98
- data/lib/http/response/body.rb +103 -18
- data/lib/http/response/inflater.rb +35 -7
- data/lib/http/response/parser.rb +98 -4
- data/lib/http/response/status/reasons.rb +2 -4
- data/lib/http/response/status.rb +141 -31
- data/lib/http/response.rb +219 -61
- data/lib/http/retriable/delay_calculator.rb +38 -11
- data/lib/http/retriable/errors.rb +21 -0
- data/lib/http/retriable/performer.rb +82 -38
- data/lib/http/session.rb +280 -0
- data/lib/http/timeout/global.rb +147 -34
- data/lib/http/timeout/null.rb +155 -9
- data/lib/http/timeout/per_operation.rb +139 -18
- data/lib/http/uri/normalizer.rb +82 -0
- data/lib/http/uri/parsing.rb +182 -0
- data/lib/http/uri.rb +289 -124
- data/lib/http/version.rb +2 -1
- data/lib/http.rb +11 -2
- data/sig/deps.rbs +122 -0
- data/sig/http.rbs +1619 -0
- data/test/http/base64_test.rb +28 -0
- data/test/http/client_test.rb +739 -0
- data/test/http/connection_test.rb +1533 -0
- data/test/http/content_type_test.rb +190 -0
- data/test/http/errors_test.rb +28 -0
- data/test/http/feature_test.rb +49 -0
- data/test/http/features/auto_deflate_test.rb +317 -0
- data/test/http/features/auto_inflate_test.rb +213 -0
- data/test/http/features/caching_test.rb +942 -0
- data/test/http/features/digest_auth_test.rb +996 -0
- data/test/http/features/instrumentation_test.rb +246 -0
- data/test/http/features/logging_test.rb +654 -0
- data/test/http/features/normalize_uri_test.rb +41 -0
- data/test/http/features/raise_error_test.rb +77 -0
- data/test/http/form_data/composite_io_test.rb +215 -0
- data/test/http/form_data/file_test.rb +255 -0
- data/test/http/form_data/fixtures/the-http-gem.info +1 -0
- data/test/http/form_data/multipart_test.rb +303 -0
- data/test/http/form_data/part_test.rb +90 -0
- data/test/http/form_data/urlencoded_test.rb +164 -0
- data/test/http/form_data_test.rb +232 -0
- data/test/http/headers/normalizer_test.rb +93 -0
- data/test/http/headers_test.rb +888 -0
- data/test/http/mime_type/json_test.rb +39 -0
- data/test/http/mime_type_test.rb +150 -0
- data/test/http/options/base_uri_test.rb +148 -0
- data/test/http/options/body_test.rb +21 -0
- data/test/http/options/features_test.rb +38 -0
- data/test/http/options/form_test.rb +21 -0
- data/test/http/options/headers_test.rb +32 -0
- data/test/http/options/json_test.rb +21 -0
- data/test/http/options/merge_test.rb +78 -0
- data/test/http/options/new_test.rb +37 -0
- data/test/http/options/proxy_test.rb +32 -0
- data/test/http/options_test.rb +575 -0
- data/test/http/redirector_test.rb +639 -0
- data/test/http/request/body_test.rb +318 -0
- data/test/http/request/builder_test.rb +623 -0
- data/test/http/request/writer_test.rb +391 -0
- data/test/http/request_test.rb +1733 -0
- data/test/http/response/body_test.rb +292 -0
- data/test/http/response/parser_test.rb +105 -0
- data/test/http/response/status_test.rb +322 -0
- data/test/http/response_test.rb +502 -0
- data/test/http/retriable/delay_calculator_test.rb +194 -0
- data/test/http/retriable/errors_test.rb +71 -0
- data/test/http/retriable/performer_test.rb +551 -0
- data/test/http/session_test.rb +424 -0
- data/test/http/timeout/global_test.rb +239 -0
- data/test/http/timeout/null_test.rb +218 -0
- data/test/http/timeout/per_operation_test.rb +220 -0
- data/test/http/uri/normalizer_test.rb +89 -0
- data/test/http/uri_test.rb +1140 -0
- data/test/http/version_test.rb +15 -0
- data/test/http_test.rb +818 -0
- data/test/regression_tests.rb +27 -0
- data/test/support/dummy_server/encoding_routes.rb +47 -0
- data/test/support/dummy_server/routes.rb +201 -0
- data/test/support/dummy_server/servlet.rb +81 -0
- data/test/support/dummy_server.rb +200 -0
- data/{spec → test}/support/fakeio.rb +2 -2
- data/test/support/http_handling_shared/connection_reuse_tests.rb +97 -0
- data/test/support/http_handling_shared/timeout_tests.rb +134 -0
- data/test/support/http_handling_shared.rb +11 -0
- data/test/support/proxy_server.rb +207 -0
- data/test/support/servers/runner.rb +67 -0
- data/{spec → test}/support/simplecov.rb +11 -2
- data/test/support/ssl_helper.rb +108 -0
- data/test/test_helper.rb +38 -0
- metadata +108 -168
- data/.github/workflows/ci.yml +0 -67
- data/.gitignore +0 -15
- data/.rspec +0 -1
- data/.rubocop/layout.yml +0 -8
- data/.rubocop/metrics.yml +0 -4
- data/.rubocop/rspec.yml +0 -9
- data/.rubocop/style.yml +0 -32
- data/.rubocop.yml +0 -11
- data/.rubocop_todo.yml +0 -219
- data/.yardopts +0 -2
- data/CHANGES_OLD.md +0 -1002
- data/Gemfile +0 -51
- data/Guardfile +0 -18
- data/Rakefile +0 -64
- data/lib/http/headers/mixin.rb +0 -34
- data/lib/http/retriable/client.rb +0 -37
- data/logo.png +0 -0
- data/spec/lib/http/client_spec.rb +0 -556
- data/spec/lib/http/connection_spec.rb +0 -88
- data/spec/lib/http/content_type_spec.rb +0 -47
- data/spec/lib/http/features/auto_deflate_spec.rb +0 -77
- data/spec/lib/http/features/auto_inflate_spec.rb +0 -86
- data/spec/lib/http/features/instrumentation_spec.rb +0 -81
- data/spec/lib/http/features/logging_spec.rb +0 -65
- data/spec/lib/http/features/raise_error_spec.rb +0 -62
- data/spec/lib/http/headers/mixin_spec.rb +0 -36
- data/spec/lib/http/headers/normalizer_spec.rb +0 -52
- data/spec/lib/http/headers_spec.rb +0 -527
- data/spec/lib/http/options/body_spec.rb +0 -15
- data/spec/lib/http/options/features_spec.rb +0 -33
- data/spec/lib/http/options/form_spec.rb +0 -15
- data/spec/lib/http/options/headers_spec.rb +0 -24
- data/spec/lib/http/options/json_spec.rb +0 -15
- data/spec/lib/http/options/merge_spec.rb +0 -68
- data/spec/lib/http/options/new_spec.rb +0 -30
- data/spec/lib/http/options/proxy_spec.rb +0 -20
- data/spec/lib/http/options_spec.rb +0 -13
- data/spec/lib/http/redirector_spec.rb +0 -530
- data/spec/lib/http/request/body_spec.rb +0 -211
- data/spec/lib/http/request/writer_spec.rb +0 -121
- data/spec/lib/http/request_spec.rb +0 -234
- data/spec/lib/http/response/body_spec.rb +0 -85
- data/spec/lib/http/response/parser_spec.rb +0 -74
- data/spec/lib/http/response/status_spec.rb +0 -253
- data/spec/lib/http/response_spec.rb +0 -262
- data/spec/lib/http/retriable/delay_calculator_spec.rb +0 -69
- data/spec/lib/http/retriable/performer_spec.rb +0 -302
- data/spec/lib/http/uri/normalizer_spec.rb +0 -95
- data/spec/lib/http/uri_spec.rb +0 -71
- data/spec/lib/http_spec.rb +0 -535
- data/spec/regression_specs.rb +0 -24
- data/spec/spec_helper.rb +0 -89
- data/spec/support/black_hole.rb +0 -13
- data/spec/support/dummy_server/servlet.rb +0 -203
- data/spec/support/dummy_server.rb +0 -44
- data/spec/support/fuubar.rb +0 -21
- data/spec/support/http_handling_shared.rb +0 -190
- data/spec/support/proxy_server.rb +0 -39
- data/spec/support/servers/config.rb +0 -11
- data/spec/support/servers/runner.rb +0 -19
- data/spec/support/ssl_helper.rb +0 -104
- /data/{spec → test}/support/capture_warning.rb +0 -0
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
class HTTPOptionsTest < Minitest::Test
|
|
6
|
+
cover "HTTP::Options*"
|
|
7
|
+
|
|
8
|
+
# .new
|
|
9
|
+
|
|
10
|
+
def test_new_returns_the_same_instance_when_given_an_options_object
|
|
11
|
+
original = HTTP::Options.new
|
|
12
|
+
result = HTTP::Options.new(original)
|
|
13
|
+
|
|
14
|
+
assert_same original, result
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_new_does_not_treat_a_hash_as_an_options_instance
|
|
18
|
+
result = HTTP::Options.new(response: :body)
|
|
19
|
+
|
|
20
|
+
assert_instance_of HTTP::Options, result
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_new_creates_from_a_hash_argument
|
|
24
|
+
result = HTTP::Options.new(response: :body)
|
|
25
|
+
|
|
26
|
+
assert_equal :body, result.response
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_new_creates_from_keyword_arguments
|
|
30
|
+
result = HTTP::Options.new(response: :object)
|
|
31
|
+
|
|
32
|
+
assert_equal :object, result.response
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def test_new_prefers_positional_hash_over_kwargs
|
|
36
|
+
result = HTTP::Options.new({ response: :body })
|
|
37
|
+
|
|
38
|
+
assert_equal :body, result.response
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# .defined_options
|
|
42
|
+
|
|
43
|
+
def test_defined_options_returns_an_array
|
|
44
|
+
assert_kind_of Array, HTTP::Options.defined_options
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_defined_options_contains_all_expected_option_names_as_symbols
|
|
48
|
+
expected = %i[
|
|
49
|
+
headers encoding features proxy params form json body response
|
|
50
|
+
socket_class nodelay ssl_socket_class ssl_context ssl
|
|
51
|
+
keep_alive_timeout timeout_class timeout_options
|
|
52
|
+
follow retriable base_uri persistent
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
expected.each do |name|
|
|
56
|
+
assert_includes HTTP::Options.defined_options, name
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# .register_feature
|
|
61
|
+
|
|
62
|
+
def test_register_feature_stores_the_feature_implementation_by_name
|
|
63
|
+
fake_feature = Class.new(HTTP::Feature)
|
|
64
|
+
HTTP::Options.register_feature(:test_feature_register, fake_feature)
|
|
65
|
+
|
|
66
|
+
assert_equal fake_feature, HTTP::Options.available_features[:test_feature_register]
|
|
67
|
+
ensure
|
|
68
|
+
HTTP::Options.available_features.delete(:test_feature_register)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# #initialize defaults
|
|
72
|
+
|
|
73
|
+
def test_initialize_defaults_response_to_auto
|
|
74
|
+
opts = HTTP::Options.new
|
|
75
|
+
|
|
76
|
+
assert_equal :auto, opts.response
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def test_initialize_defaults_keep_alive_timeout_to_5
|
|
80
|
+
opts = HTTP::Options.new
|
|
81
|
+
|
|
82
|
+
assert_equal 5, opts.keep_alive_timeout
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def test_initialize_defaults_nodelay_to_false
|
|
86
|
+
opts = HTTP::Options.new
|
|
87
|
+
|
|
88
|
+
refute opts.nodelay
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def test_initialize_defaults_headers_to_empty
|
|
92
|
+
opts = HTTP::Options.new
|
|
93
|
+
|
|
94
|
+
assert_empty opts.headers
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def test_initialize_defaults_ssl_to_empty_hash
|
|
98
|
+
opts = HTTP::Options.new
|
|
99
|
+
|
|
100
|
+
assert_equal({}, opts.ssl)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def test_initialize_defaults_timeout_options_to_empty_hash
|
|
104
|
+
opts = HTTP::Options.new
|
|
105
|
+
|
|
106
|
+
assert_equal({}, opts.timeout_options)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_initialize_defaults_proxy_to_empty_hash
|
|
110
|
+
opts = HTTP::Options.new
|
|
111
|
+
|
|
112
|
+
assert_equal({}, opts.proxy)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def test_initialize_defaults_features_to_empty_hash
|
|
116
|
+
opts = HTTP::Options.new
|
|
117
|
+
|
|
118
|
+
assert_equal({}, opts.features)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def test_initialize_defaults_timeout_class_to_timeout_null
|
|
122
|
+
opts = HTTP::Options.new
|
|
123
|
+
|
|
124
|
+
assert_equal HTTP::Timeout::Null, opts.timeout_class
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def test_initialize_defaults_socket_class_to_tcpsocket
|
|
128
|
+
opts = HTTP::Options.new
|
|
129
|
+
|
|
130
|
+
assert_equal TCPSocket, opts.socket_class
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def test_initialize_defaults_ssl_socket_class_to_openssl_ssl_sslsocket
|
|
134
|
+
opts = HTTP::Options.new
|
|
135
|
+
|
|
136
|
+
assert_equal OpenSSL::SSL::SSLSocket, opts.ssl_socket_class
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def test_initialize_defaults_encoding_to_nil
|
|
140
|
+
opts = HTTP::Options.new
|
|
141
|
+
|
|
142
|
+
assert_nil opts.encoding
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def test_initialize_defaults_params_to_nil
|
|
146
|
+
opts = HTTP::Options.new
|
|
147
|
+
|
|
148
|
+
assert_nil opts.params
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def test_initialize_defaults_form_to_nil
|
|
152
|
+
opts = HTTP::Options.new
|
|
153
|
+
|
|
154
|
+
assert_nil opts.form
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def test_initialize_defaults_json_to_nil
|
|
158
|
+
opts = HTTP::Options.new
|
|
159
|
+
|
|
160
|
+
assert_nil opts.json
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def test_initialize_defaults_body_to_nil
|
|
164
|
+
opts = HTTP::Options.new
|
|
165
|
+
|
|
166
|
+
assert_nil opts.body
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def test_initialize_defaults_follow_to_nil
|
|
170
|
+
opts = HTTP::Options.new
|
|
171
|
+
|
|
172
|
+
assert_nil opts.follow
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def test_initialize_defaults_retriable_to_nil
|
|
176
|
+
opts = HTTP::Options.new
|
|
177
|
+
|
|
178
|
+
assert_nil opts.retriable
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def test_initialize_defaults_base_uri_to_nil
|
|
182
|
+
opts = HTTP::Options.new
|
|
183
|
+
|
|
184
|
+
assert_nil opts.base_uri
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def test_initialize_defaults_persistent_to_nil
|
|
188
|
+
opts = HTTP::Options.new
|
|
189
|
+
|
|
190
|
+
assert_nil opts.persistent
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def test_initialize_defaults_ssl_context_to_nil
|
|
194
|
+
opts = HTTP::Options.new
|
|
195
|
+
|
|
196
|
+
assert_nil opts.ssl_context
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# #to_hash
|
|
200
|
+
|
|
201
|
+
def test_to_hash_contains_all_defined_options
|
|
202
|
+
opts = HTTP::Options.new
|
|
203
|
+
hash = opts.to_hash
|
|
204
|
+
|
|
205
|
+
HTTP::Options.defined_options.each do |name|
|
|
206
|
+
assert_includes hash.keys, name
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def test_to_hash_returns_correct_values_for_custom_options
|
|
211
|
+
custom = HTTP::Options.new(response: :body, keep_alive_timeout: 10)
|
|
212
|
+
hash = custom.to_hash
|
|
213
|
+
|
|
214
|
+
assert_equal :body, hash[:response]
|
|
215
|
+
assert_equal 10, hash[:keep_alive_timeout]
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# #merge
|
|
219
|
+
|
|
220
|
+
def test_merge_merges_headers_by_combining_them
|
|
221
|
+
opts1 = HTTP::Options.new(headers: { foo: "bar" })
|
|
222
|
+
opts2 = HTTP::Options.new(headers: { baz: "qux" })
|
|
223
|
+
merged = opts1.merge(opts2)
|
|
224
|
+
|
|
225
|
+
assert_equal "bar", merged.headers["Foo"]
|
|
226
|
+
assert_equal "qux", merged.headers["Baz"]
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def test_merge_replaces_non_header_values
|
|
230
|
+
opts1 = HTTP::Options.new(response: :auto)
|
|
231
|
+
merged = opts1.merge(response: :body)
|
|
232
|
+
|
|
233
|
+
assert_equal :body, merged.response
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# #dup
|
|
237
|
+
|
|
238
|
+
def test_dup_returns_a_duplicate
|
|
239
|
+
opts = HTTP::Options.new
|
|
240
|
+
dupped = opts.dup
|
|
241
|
+
|
|
242
|
+
assert_equal :auto, dupped.response
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def test_dup_yields_the_duplicate_when_a_block_is_given
|
|
246
|
+
opts = HTTP::Options.new
|
|
247
|
+
yielded = nil
|
|
248
|
+
dupped = opts.dup { |d| yielded = d }
|
|
249
|
+
|
|
250
|
+
assert_same dupped, yielded
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# #feature
|
|
254
|
+
|
|
255
|
+
def test_feature_returns_nil_for_unregistered_feature
|
|
256
|
+
opts = HTTP::Options.new
|
|
257
|
+
|
|
258
|
+
assert_nil opts.feature(:nonexistent)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def test_feature_returns_the_feature_instance_for_a_registered_feature
|
|
262
|
+
opts = HTTP::Options.new
|
|
263
|
+
opts_with = opts.with_features([:auto_inflate])
|
|
264
|
+
|
|
265
|
+
assert_instance_of HTTP::Features::AutoInflate, opts_with.feature(:auto_inflate)
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# #with_follow
|
|
269
|
+
|
|
270
|
+
def test_with_follow_sets_follow_to_empty_hash_when_true
|
|
271
|
+
opts = HTTP::Options.new
|
|
272
|
+
result = opts.with_follow(true)
|
|
273
|
+
|
|
274
|
+
assert_equal({}, result.follow)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def test_with_follow_sets_follow_to_nil_when_false
|
|
278
|
+
opts = HTTP::Options.new
|
|
279
|
+
result = opts.with_follow(false)
|
|
280
|
+
|
|
281
|
+
assert_nil result.follow
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def test_with_follow_sets_follow_to_nil_when_nil
|
|
285
|
+
opts = HTTP::Options.new
|
|
286
|
+
result = opts.with_follow(nil)
|
|
287
|
+
|
|
288
|
+
assert_nil result.follow
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def test_with_follow_passes_through_hash_options
|
|
292
|
+
opts = HTTP::Options.new
|
|
293
|
+
result = opts.with_follow(max_hops: 5)
|
|
294
|
+
|
|
295
|
+
assert_equal({ max_hops: 5 }, result.follow)
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def test_with_follow_raises_error_for_unsupported_follow_value
|
|
299
|
+
opts = HTTP::Options.new
|
|
300
|
+
err = assert_raises(HTTP::Error) { opts.with_follow(42) }
|
|
301
|
+
|
|
302
|
+
assert_match(/Unsupported follow/, err.message)
|
|
303
|
+
assert_includes err.message, "42"
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def test_with_follow_does_not_modify_original
|
|
307
|
+
opts = HTTP::Options.new
|
|
308
|
+
opts.with_follow(true)
|
|
309
|
+
|
|
310
|
+
assert_nil opts.follow
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# #with_retriable
|
|
314
|
+
|
|
315
|
+
def test_with_retriable_sets_retriable_to_empty_hash_when_true
|
|
316
|
+
opts = HTTP::Options.new
|
|
317
|
+
result = opts.with_retriable(true)
|
|
318
|
+
|
|
319
|
+
assert_equal({}, result.retriable)
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
def test_with_retriable_sets_retriable_to_nil_when_false
|
|
323
|
+
opts = HTTP::Options.new
|
|
324
|
+
result = opts.with_retriable(false)
|
|
325
|
+
|
|
326
|
+
assert_nil result.retriable
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
def test_with_retriable_sets_retriable_to_nil_when_nil
|
|
330
|
+
opts = HTTP::Options.new
|
|
331
|
+
result = opts.with_retriable(nil)
|
|
332
|
+
|
|
333
|
+
assert_nil result.retriable
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def test_with_retriable_passes_through_hash_options
|
|
337
|
+
opts = HTTP::Options.new
|
|
338
|
+
result = opts.with_retriable(max_retries: 3)
|
|
339
|
+
|
|
340
|
+
assert_equal({ max_retries: 3 }, result.retriable)
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
def test_with_retriable_raises_error_for_unsupported_retriable_value
|
|
344
|
+
opts = HTTP::Options.new
|
|
345
|
+
err = assert_raises(HTTP::Error) { opts.with_retriable(42) }
|
|
346
|
+
|
|
347
|
+
assert_match(/Unsupported retriable/, err.message)
|
|
348
|
+
assert_includes err.message, "42"
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
def test_with_retriable_does_not_modify_original
|
|
352
|
+
opts = HTTP::Options.new
|
|
353
|
+
opts.with_retriable(true)
|
|
354
|
+
|
|
355
|
+
assert_nil opts.retriable
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
# #persistent?
|
|
359
|
+
|
|
360
|
+
def test_persistent_returns_false_by_default
|
|
361
|
+
opts = HTTP::Options.new
|
|
362
|
+
|
|
363
|
+
refute_predicate opts, :persistent?
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
def test_persistent_returns_true_when_persistent_is_set
|
|
367
|
+
opts = HTTP::Options.new
|
|
368
|
+
result = opts.with_persistent("https://example.com")
|
|
369
|
+
|
|
370
|
+
assert_predicate result, :persistent?
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
# #with_persistent
|
|
374
|
+
|
|
375
|
+
def test_with_persistent_sets_persistent_to_origin
|
|
376
|
+
opts = HTTP::Options.new
|
|
377
|
+
result = opts.with_persistent("https://example.com/path")
|
|
378
|
+
|
|
379
|
+
assert_equal "https://example.com", result.persistent
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
def test_with_persistent_clears_persistent_when_set_to_nil
|
|
383
|
+
opts = HTTP::Options.new
|
|
384
|
+
with_persistent = opts.with_persistent("https://example.com")
|
|
385
|
+
result = with_persistent.with_persistent(nil)
|
|
386
|
+
|
|
387
|
+
assert_nil result.persistent
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
# #with_encoding
|
|
391
|
+
|
|
392
|
+
def test_with_encoding_finds_encoding_by_name
|
|
393
|
+
opts = HTTP::Options.new
|
|
394
|
+
result = opts.with_encoding("UTF-8")
|
|
395
|
+
|
|
396
|
+
assert_equal Encoding::UTF_8, result.encoding
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
# #features=
|
|
400
|
+
|
|
401
|
+
def test_features_accepts_pre_built_feature_instances
|
|
402
|
+
feature_instance = HTTP::Features::AutoInflate.new
|
|
403
|
+
result = HTTP::Options.new(features: { auto_inflate: feature_instance })
|
|
404
|
+
|
|
405
|
+
assert_same feature_instance, result.features[:auto_inflate]
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
def test_features_raises_for_unsupported_feature_names
|
|
409
|
+
err = assert_raises(HTTP::Error) { HTTP::Options.new(features: { bogus: {} }) }
|
|
410
|
+
|
|
411
|
+
assert_equal "Unsupported feature: bogus", err.message
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
# with_ methods for simple options
|
|
415
|
+
|
|
416
|
+
def test_with_proxy_returns_new_options_with_updated_proxy
|
|
417
|
+
opts = HTTP::Options.new
|
|
418
|
+
result = opts.with_proxy(proxy_address: "127.0.0.1")
|
|
419
|
+
|
|
420
|
+
assert_equal({ proxy_address: "127.0.0.1" }, result.proxy)
|
|
421
|
+
assert_equal({}, opts.proxy)
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
def test_with_params_returns_new_options_with_updated_params
|
|
425
|
+
opts = HTTP::Options.new
|
|
426
|
+
result = opts.with_params(foo: "bar")
|
|
427
|
+
|
|
428
|
+
assert_equal({ foo: "bar" }, result.params)
|
|
429
|
+
assert_nil opts.params
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
def test_with_form_returns_new_options_with_updated_form
|
|
433
|
+
opts = HTTP::Options.new
|
|
434
|
+
result = opts.with_form(foo: 42)
|
|
435
|
+
|
|
436
|
+
assert_equal({ foo: 42 }, result.form)
|
|
437
|
+
assert_nil opts.form
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
def test_with_json_returns_new_options_with_updated_json
|
|
441
|
+
opts = HTTP::Options.new
|
|
442
|
+
result = opts.with_json(foo: 42)
|
|
443
|
+
|
|
444
|
+
assert_equal({ foo: 42 }, result.json)
|
|
445
|
+
assert_nil opts.json
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
def test_with_body_returns_new_options_with_updated_body
|
|
449
|
+
opts = HTTP::Options.new
|
|
450
|
+
result = opts.with_body("data")
|
|
451
|
+
|
|
452
|
+
assert_equal "data", result.body
|
|
453
|
+
assert_nil opts.body
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
def test_with_response_returns_new_options_with_updated_response
|
|
457
|
+
opts = HTTP::Options.new
|
|
458
|
+
result = opts.with_response(:body)
|
|
459
|
+
|
|
460
|
+
assert_equal :body, result.response
|
|
461
|
+
assert_equal :auto, opts.response
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
def test_with_socket_class_returns_new_options
|
|
465
|
+
opts = HTTP::Options.new
|
|
466
|
+
custom_class = Class.new
|
|
467
|
+
result = opts.with_socket_class(custom_class)
|
|
468
|
+
|
|
469
|
+
assert_equal custom_class, result.socket_class
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
def test_with_nodelay_returns_new_options
|
|
473
|
+
opts = HTTP::Options.new
|
|
474
|
+
result = opts.with_nodelay(true)
|
|
475
|
+
|
|
476
|
+
assert result.nodelay
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
def test_with_ssl_socket_class_returns_new_options
|
|
480
|
+
opts = HTTP::Options.new
|
|
481
|
+
custom_class = Class.new
|
|
482
|
+
result = opts.with_ssl_socket_class(custom_class)
|
|
483
|
+
|
|
484
|
+
assert_equal custom_class, result.ssl_socket_class
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
def test_with_ssl_context_returns_new_options
|
|
488
|
+
opts = HTTP::Options.new
|
|
489
|
+
ctx = OpenSSL::SSL::SSLContext.new
|
|
490
|
+
result = opts.with_ssl_context(ctx)
|
|
491
|
+
|
|
492
|
+
assert_equal ctx, result.ssl_context
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
def test_with_ssl_returns_new_options
|
|
496
|
+
opts = HTTP::Options.new
|
|
497
|
+
result = opts.with_ssl(verify_mode: OpenSSL::SSL::VERIFY_NONE)
|
|
498
|
+
|
|
499
|
+
assert_equal({ verify_mode: OpenSSL::SSL::VERIFY_NONE }, result.ssl)
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
def test_with_keep_alive_timeout_returns_new_options
|
|
503
|
+
opts = HTTP::Options.new
|
|
504
|
+
result = opts.with_keep_alive_timeout(10)
|
|
505
|
+
|
|
506
|
+
assert_equal 10, result.keep_alive_timeout
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
def test_with_timeout_class_returns_new_options
|
|
510
|
+
opts = HTTP::Options.new
|
|
511
|
+
custom_class = Class.new
|
|
512
|
+
result = opts.with_timeout_class(custom_class)
|
|
513
|
+
|
|
514
|
+
assert_equal custom_class, result.timeout_class
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
def test_with_timeout_options_returns_new_options
|
|
518
|
+
opts = HTTP::Options.new
|
|
519
|
+
result = opts.with_timeout_options(read_timeout: 5)
|
|
520
|
+
|
|
521
|
+
assert_equal({ read_timeout: 5 }, result.timeout_options)
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
# #argument_error! backtrace
|
|
525
|
+
|
|
526
|
+
def test_argument_error_excludes_argument_error_from_the_backtrace
|
|
527
|
+
opts = HTTP::Options.new
|
|
528
|
+
err = assert_raises(HTTP::Error) { opts.with_follow(42) }
|
|
529
|
+
|
|
530
|
+
refute err.backtrace.any? { |line| line.include?("argument_error!") },
|
|
531
|
+
"backtrace should not include argument_error! method"
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
def test_argument_error_starts_the_backtrace_at_the_calling_setter_method
|
|
535
|
+
opts = HTTP::Options.new
|
|
536
|
+
err = assert_raises(HTTP::Error) { opts.with_follow(42) }
|
|
537
|
+
|
|
538
|
+
assert_includes err.backtrace.first, "definitions.rb"
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
def test_argument_error_includes_more_than_one_backtrace_frame
|
|
542
|
+
opts = HTTP::Options.new
|
|
543
|
+
err = assert_raises(HTTP::Error) { opts.with_follow(42) }
|
|
544
|
+
|
|
545
|
+
assert_operator err.backtrace.length, :>, 1
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
def test_argument_error_preserves_the_full_backtrace_down_to_the_bottom_of_the_stack
|
|
549
|
+
opts = HTTP::Options.new
|
|
550
|
+
ref_err = begin; raise HTTP::Error, "ref"; rescue HTTP::Error => e; e; end
|
|
551
|
+
arg_err = assert_raises(HTTP::Error) { opts.with_follow(42) }
|
|
552
|
+
|
|
553
|
+
assert_equal ref_err.backtrace.last, arg_err.backtrace.last
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
# non-reader_only options have protected writers
|
|
557
|
+
|
|
558
|
+
def test_response_writer_is_protected
|
|
559
|
+
opts = HTTP::Options.new
|
|
560
|
+
|
|
561
|
+
assert_raises(NoMethodError) { opts.response = :body }
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
def test_proxy_writer_is_protected
|
|
565
|
+
opts = HTTP::Options.new
|
|
566
|
+
|
|
567
|
+
assert_raises(NoMethodError) { opts.proxy = {} }
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
def test_keep_alive_timeout_writer_is_protected
|
|
571
|
+
opts = HTTP::Options.new
|
|
572
|
+
|
|
573
|
+
assert_raises(NoMethodError) { opts.keep_alive_timeout = 10 }
|
|
574
|
+
end
|
|
575
|
+
end
|