webmock 3.5.0 → 3.25.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 +476 -2
- data/README.md +166 -42
- data/lib/webmock/api.rb +2 -0
- data/lib/webmock/assertion_failure.rb +2 -0
- data/lib/webmock/callback_registry.rb +2 -0
- data/lib/webmock/config.rb +2 -0
- data/lib/webmock/cucumber.rb +2 -0
- data/lib/webmock/deprecation.rb +2 -0
- data/lib/webmock/errors.rb +2 -0
- data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +228 -0
- data/lib/webmock/http_lib_adapters/curb_adapter.rb +14 -3
- data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +22 -9
- data/lib/webmock/http_lib_adapters/excon_adapter.rb +5 -0
- data/lib/webmock/http_lib_adapters/http_lib_adapter.rb +2 -0
- data/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +2 -0
- data/lib/webmock/http_lib_adapters/http_rb/client.rb +4 -1
- data/lib/webmock/http_lib_adapters/http_rb/request.rb +17 -5
- data/lib/webmock/http_lib_adapters/http_rb/response.rb +49 -5
- data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +11 -3
- data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +8 -2
- data/lib/webmock/http_lib_adapters/http_rb_adapter.rb +7 -5
- data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +25 -7
- data/lib/webmock/http_lib_adapters/manticore_adapter.rb +35 -15
- data/lib/webmock/http_lib_adapters/net_http.rb +59 -112
- data/lib/webmock/http_lib_adapters/net_http_response.rb +3 -1
- data/lib/webmock/http_lib_adapters/patron_adapter.rb +4 -2
- data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +18 -2
- data/lib/webmock/matchers/any_arg_matcher.rb +2 -0
- data/lib/webmock/matchers/hash_argument_matcher.rb +2 -0
- data/lib/webmock/matchers/hash_excluding_matcher.rb +2 -0
- data/lib/webmock/matchers/hash_including_matcher.rb +2 -0
- data/lib/webmock/minitest.rb +2 -0
- data/lib/webmock/rack_response.rb +5 -1
- data/lib/webmock/request_body_diff.rb +3 -1
- data/lib/webmock/request_execution_verifier.rb +2 -0
- data/lib/webmock/request_pattern.rb +118 -61
- data/lib/webmock/request_registry.rb +2 -0
- data/lib/webmock/request_signature.rb +4 -2
- data/lib/webmock/request_signature_snippet.rb +2 -0
- data/lib/webmock/request_stub.rb +34 -0
- data/lib/webmock/response.rb +22 -14
- data/lib/webmock/responses_sequence.rb +2 -0
- data/lib/webmock/rspec/matchers/request_pattern_matcher.rb +2 -0
- data/lib/webmock/rspec/matchers/webmock_matcher.rb +2 -0
- data/lib/webmock/rspec/matchers.rb +2 -0
- data/lib/webmock/rspec.rb +4 -1
- data/lib/webmock/stub_registry.rb +28 -11
- data/lib/webmock/stub_request_snippet.rb +2 -0
- data/lib/webmock/test_unit.rb +3 -3
- data/lib/webmock/util/hash_counter.rb +12 -6
- data/lib/webmock/util/hash_keys_stringifier.rb +2 -0
- data/lib/webmock/util/hash_validator.rb +2 -0
- data/lib/webmock/util/headers.rb +23 -10
- data/lib/webmock/util/parsers/json.rb +72 -0
- data/lib/webmock/util/parsers/parse_error.rb +7 -0
- data/lib/webmock/util/parsers/xml.rb +16 -0
- data/lib/webmock/util/query_mapper.rb +6 -2
- data/lib/webmock/util/uri.rb +11 -9
- data/lib/webmock/util/values_stringifier.rb +2 -0
- data/lib/webmock/util/version_checker.rb +7 -5
- data/lib/webmock/version.rb +3 -1
- data/lib/webmock/webmock.rb +22 -3
- data/lib/webmock.rb +5 -2
- metadata +99 -175
- data/.gemtest +0 -0
- data/.gitignore +0 -34
- data/.rspec-tm +0 -2
- data/.travis.yml +0 -21
- data/Gemfile +0 -9
- data/Rakefile +0 -30
- data/lib/webmock/util/json.rb +0 -67
- data/minitest/test_helper.rb +0 -34
- data/minitest/test_webmock.rb +0 -9
- data/minitest/webmock_spec.rb +0 -60
- data/spec/acceptance/curb/curb_spec.rb +0 -481
- data/spec/acceptance/curb/curb_spec_helper.rb +0 -147
- data/spec/acceptance/em_http_request/em_http_request_spec.rb +0 -406
- data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +0 -77
- data/spec/acceptance/excon/excon_spec.rb +0 -77
- data/spec/acceptance/excon/excon_spec_helper.rb +0 -50
- data/spec/acceptance/http_rb/http_rb_spec.rb +0 -82
- data/spec/acceptance/http_rb/http_rb_spec_helper.rb +0 -54
- data/spec/acceptance/httpclient/httpclient_spec.rb +0 -217
- data/spec/acceptance/httpclient/httpclient_spec_helper.rb +0 -57
- data/spec/acceptance/manticore/manticore_spec.rb +0 -56
- data/spec/acceptance/manticore/manticore_spec_helper.rb +0 -35
- data/spec/acceptance/net_http/net_http_shared.rb +0 -153
- data/spec/acceptance/net_http/net_http_spec.rb +0 -331
- data/spec/acceptance/net_http/net_http_spec_helper.rb +0 -64
- data/spec/acceptance/net_http/real_net_http_spec.rb +0 -20
- data/spec/acceptance/patron/patron_spec.rb +0 -125
- data/spec/acceptance/patron/patron_spec_helper.rb +0 -54
- data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +0 -313
- data/spec/acceptance/shared/callbacks.rb +0 -147
- data/spec/acceptance/shared/complex_cross_concern_behaviors.rb +0 -36
- data/spec/acceptance/shared/enabling_and_disabling_webmock.rb +0 -95
- data/spec/acceptance/shared/precedence_of_stubs.rb +0 -15
- data/spec/acceptance/shared/request_expectations.rb +0 -923
- data/spec/acceptance/shared/returning_declared_responses.rb +0 -388
- data/spec/acceptance/shared/stubbing_requests.rb +0 -638
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +0 -135
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +0 -60
- data/spec/acceptance/webmock_shared.rb +0 -41
- data/spec/fixtures/test.txt +0 -1
- data/spec/quality_spec.rb +0 -84
- data/spec/spec_helper.rb +0 -48
- data/spec/support/example_curl_output.txt +0 -22
- data/spec/support/failures.rb +0 -9
- data/spec/support/my_rack_app.rb +0 -53
- data/spec/support/network_connection.rb +0 -19
- data/spec/support/webmock_server.rb +0 -69
- data/spec/unit/api_spec.rb +0 -175
- data/spec/unit/errors_spec.rb +0 -129
- data/spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb +0 -17
- data/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +0 -12
- data/spec/unit/matchers/hash_excluding_matcher_spec.rb +0 -61
- data/spec/unit/matchers/hash_including_matcher_spec.rb +0 -87
- data/spec/unit/rack_response_spec.rb +0 -112
- data/spec/unit/request_body_diff_spec.rb +0 -90
- data/spec/unit/request_execution_verifier_spec.rb +0 -208
- data/spec/unit/request_pattern_spec.rb +0 -596
- data/spec/unit/request_registry_spec.rb +0 -95
- data/spec/unit/request_signature_snippet_spec.rb +0 -89
- data/spec/unit/request_signature_spec.rb +0 -155
- data/spec/unit/request_stub_spec.rb +0 -199
- data/spec/unit/response_spec.rb +0 -282
- data/spec/unit/stub_registry_spec.rb +0 -103
- data/spec/unit/stub_request_snippet_spec.rb +0 -115
- data/spec/unit/util/hash_counter_spec.rb +0 -39
- data/spec/unit/util/hash_keys_stringifier_spec.rb +0 -27
- data/spec/unit/util/headers_spec.rb +0 -28
- data/spec/unit/util/json_spec.rb +0 -33
- data/spec/unit/util/query_mapper_spec.rb +0 -150
- data/spec/unit/util/uri_spec.rb +0 -299
- data/spec/unit/util/version_checker_spec.rb +0 -65
- data/spec/unit/webmock_spec.rb +0 -11
- data/test/http_request.rb +0 -24
- data/test/shared_test.rb +0 -108
- data/test/test_helper.rb +0 -23
- data/test/test_webmock.rb +0 -6
- data/webmock.gemspec +0 -46
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module WebMock
|
2
4
|
|
3
5
|
module RSpecMatcherDetector
|
@@ -24,7 +26,7 @@ module WebMock
|
|
24
26
|
end
|
25
27
|
|
26
28
|
def with(options = {}, &block)
|
27
|
-
raise ArgumentError.new('#with method invoked with no arguments. Either options hash or block must be specified.') if options.empty? && !block_given?
|
29
|
+
raise ArgumentError.new('#with method invoked with no arguments. Either options hash or block must be specified. Created a block with do..end? Try creating it with curly braces {} instead.') if options.empty? && !block_given?
|
28
30
|
assign_options(options)
|
29
31
|
@with_block = block
|
30
32
|
self
|
@@ -80,11 +82,16 @@ module WebMock
|
|
80
82
|
URIRegexpPattern.new(uri)
|
81
83
|
elsif uri.is_a?(Addressable::Template)
|
82
84
|
URIAddressablePattern.new(uri)
|
83
|
-
|
85
|
+
elsif uri.respond_to?(:call)
|
86
|
+
URICallablePattern.new(uri)
|
87
|
+
elsif uri.is_a?(::URI::Generic)
|
88
|
+
URIStringPattern.new(uri.to_s)
|
89
|
+
elsif uri.is_a?(String)
|
84
90
|
URIStringPattern.new(uri)
|
91
|
+
else
|
92
|
+
raise ArgumentError.new("URI should be a String, Regexp, Addressable::Template or a callable object. Got: #{uri.class}")
|
85
93
|
end
|
86
94
|
end
|
87
|
-
|
88
95
|
end
|
89
96
|
|
90
97
|
|
@@ -107,11 +114,13 @@ module WebMock
|
|
107
114
|
include RSpecMatcherDetector
|
108
115
|
|
109
116
|
def initialize(pattern)
|
110
|
-
@pattern =
|
111
|
-
|
117
|
+
@pattern = if pattern.is_a?(Addressable::URI) \
|
118
|
+
|| pattern.is_a?(Addressable::Template)
|
119
|
+
pattern
|
120
|
+
elsif pattern.respond_to?(:call)
|
112
121
|
pattern
|
113
122
|
else
|
114
|
-
|
123
|
+
WebMock::Util::URI.normalize_uri(pattern)
|
115
124
|
end
|
116
125
|
@query_params = nil
|
117
126
|
end
|
@@ -131,38 +140,44 @@ module WebMock
|
|
131
140
|
end
|
132
141
|
end
|
133
142
|
|
143
|
+
def matches?(uri)
|
144
|
+
pattern_matches?(uri) && query_params_matches?(uri)
|
145
|
+
end
|
146
|
+
|
134
147
|
def to_s
|
135
|
-
str =
|
148
|
+
str = pattern_inspect
|
136
149
|
str += " with query params #{@query_params.inspect}" if @query_params
|
137
150
|
str
|
138
151
|
end
|
139
|
-
end
|
140
152
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
153
|
+
private
|
154
|
+
|
155
|
+
def pattern_inspect
|
156
|
+
@pattern.inspect
|
145
157
|
end
|
146
158
|
|
147
|
-
def
|
148
|
-
|
149
|
-
str += " with query params #{@query_params.inspect}" if @query_params
|
150
|
-
str
|
159
|
+
def query_params_matches?(uri)
|
160
|
+
@query_params.nil? || @query_params == WebMock::Util::QueryMapper.query_to_values(uri.query, notation: Config.instance.query_values_notation)
|
151
161
|
end
|
152
162
|
end
|
153
163
|
|
154
|
-
class
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
else
|
160
|
-
# WebMock checks the query, Addressable checks everything else
|
161
|
-
matches_with_variations?(uri.omit(:query)) &&
|
162
|
-
@query_params == WebMock::Util::QueryMapper.query_to_values(uri.query)
|
163
|
-
end
|
164
|
+
class URICallablePattern < URIPattern
|
165
|
+
private
|
166
|
+
|
167
|
+
def pattern_matches?(uri)
|
168
|
+
@pattern.call(uri)
|
164
169
|
end
|
170
|
+
end
|
165
171
|
|
172
|
+
class URIRegexpPattern < URIPattern
|
173
|
+
private
|
174
|
+
|
175
|
+
def pattern_matches?(uri)
|
176
|
+
WebMock::Util::URI.variations_of_uri_as_strings(uri).any? { |u| u.match(@pattern) }
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
class URIAddressablePattern < URIPattern
|
166
181
|
def add_query_params(query_params)
|
167
182
|
@@add_query_params_warned ||= false
|
168
183
|
if not @@add_query_params_warned
|
@@ -172,28 +187,57 @@ module WebMock
|
|
172
187
|
super(query_params)
|
173
188
|
end
|
174
189
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
190
|
+
private
|
191
|
+
|
192
|
+
def pattern_matches?(uri)
|
193
|
+
if @query_params.nil?
|
194
|
+
# Let Addressable check the whole URI
|
195
|
+
matches_with_variations?(uri)
|
196
|
+
else
|
197
|
+
# WebMock checks the query, Addressable checks everything else
|
198
|
+
matches_with_variations?(uri.omit(:query))
|
199
|
+
end
|
179
200
|
end
|
180
201
|
|
181
|
-
|
202
|
+
def pattern_inspect
|
203
|
+
@pattern.pattern.inspect
|
204
|
+
end
|
182
205
|
|
183
206
|
def matches_with_variations?(uri)
|
184
|
-
|
207
|
+
template =
|
208
|
+
begin
|
209
|
+
Addressable::Template.new(WebMock::Util::URI.heuristic_parse(@pattern.pattern))
|
210
|
+
rescue Addressable::URI::InvalidURIError
|
211
|
+
Addressable::Template.new(@pattern.pattern)
|
212
|
+
end
|
213
|
+
WebMock::Util::URI.variations_of_uri_as_strings(uri).any? { |u|
|
214
|
+
template_matches_uri?(template, u)
|
215
|
+
}
|
216
|
+
end
|
185
217
|
|
186
|
-
|
187
|
-
|
218
|
+
def template_matches_uri?(template, uri)
|
219
|
+
template.match(uri)
|
220
|
+
rescue Addressable::URI::InvalidURIError
|
221
|
+
false
|
188
222
|
end
|
189
223
|
end
|
190
224
|
|
191
225
|
class URIStringPattern < URIPattern
|
192
|
-
def
|
226
|
+
def add_query_params(query_params)
|
227
|
+
super
|
228
|
+
if @query_params.is_a?(Hash) || @query_params.is_a?(String)
|
229
|
+
query_hash = (WebMock::Util::QueryMapper.query_to_values(@pattern.query, notation: Config.instance.query_values_notation) || {}).merge(@query_params)
|
230
|
+
@pattern.query = WebMock::Util::QueryMapper.values_to_query(query_hash, notation: WebMock::Config.instance.query_values_notation)
|
231
|
+
@query_params = nil
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
private
|
236
|
+
|
237
|
+
def pattern_matches?(uri)
|
193
238
|
if @pattern.is_a?(Addressable::URI)
|
194
239
|
if @query_params
|
195
|
-
uri.omit(:query) === @pattern
|
196
|
-
(@query_params.nil? || @query_params == WebMock::Util::QueryMapper.query_to_values(uri.query, notation: Config.instance.query_values_notation))
|
240
|
+
uri.omit(:query) === @pattern
|
197
241
|
else
|
198
242
|
uri === @pattern
|
199
243
|
end
|
@@ -202,19 +246,8 @@ module WebMock
|
|
202
246
|
end
|
203
247
|
end
|
204
248
|
|
205
|
-
def
|
206
|
-
|
207
|
-
if @query_params.is_a?(Hash) || @query_params.is_a?(String)
|
208
|
-
query_hash = (WebMock::Util::QueryMapper.query_to_values(@pattern.query, notation: Config.instance.query_values_notation) || {}).merge(@query_params)
|
209
|
-
@pattern.query = WebMock::Util::QueryMapper.values_to_query(query_hash, notation: WebMock::Config.instance.query_values_notation)
|
210
|
-
@query_params = nil
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
def to_s
|
215
|
-
str = WebMock::Util::URI.strip_default_port_from_uri_string(@pattern.to_s)
|
216
|
-
str += " with query params #{@query_params.inspect}" if @query_params
|
217
|
-
str
|
249
|
+
def pattern_inspect
|
250
|
+
WebMock::Util::URI.strip_default_port_from_uri_string(@pattern.to_s)
|
218
251
|
end
|
219
252
|
end
|
220
253
|
|
@@ -253,7 +286,9 @@ module WebMock
|
|
253
286
|
if (@pattern).is_a?(Hash)
|
254
287
|
return true if @pattern.empty?
|
255
288
|
matching_body_hashes?(body_as_hash(body, content_type), @pattern, content_type)
|
256
|
-
elsif (@pattern).is_a?(
|
289
|
+
elsif (@pattern).is_a?(Array)
|
290
|
+
matching_body_array?(body_as_hash(body, content_type), @pattern, content_type)
|
291
|
+
elsif (@pattern).is_a?(WebMock::Matchers::HashArgumentMatcher)
|
257
292
|
@pattern == body_as_hash(body, content_type)
|
258
293
|
else
|
259
294
|
empty_string?(@pattern) && empty_string?(body) ||
|
@@ -267,15 +302,23 @@ module WebMock
|
|
267
302
|
end
|
268
303
|
|
269
304
|
private
|
305
|
+
|
270
306
|
def body_as_hash(body, content_type)
|
271
|
-
case
|
307
|
+
case body_format(content_type)
|
272
308
|
when :json then
|
273
|
-
WebMock::Util::JSON.parse(body)
|
309
|
+
WebMock::Util::Parsers::JSON.parse(body)
|
274
310
|
when :xml then
|
275
|
-
|
311
|
+
WebMock::Util::Parsers::XML.parse(body)
|
276
312
|
else
|
277
313
|
WebMock::Util::QueryMapper.query_to_values(body, notation: Config.instance.query_values_notation)
|
278
314
|
end
|
315
|
+
rescue WebMock::Util::Parsers::ParseError
|
316
|
+
nil
|
317
|
+
end
|
318
|
+
|
319
|
+
def body_format(content_type)
|
320
|
+
normalized_content_type = content_type.sub(/\A(application\/)[a-zA-Z0-9.-]+\+(json|xml)\Z/,'\1\2')
|
321
|
+
BODY_FORMATS[normalized_content_type]
|
279
322
|
end
|
280
323
|
|
281
324
|
def assert_non_multipart_body(content_type)
|
@@ -310,19 +353,33 @@ module WebMock
|
|
310
353
|
def matching_body_hashes?(query_parameters, pattern, content_type)
|
311
354
|
return false unless query_parameters.is_a?(Hash)
|
312
355
|
return false unless query_parameters.keys.sort == pattern.keys.sort
|
313
|
-
|
356
|
+
|
357
|
+
query_parameters.all? do |key, actual|
|
314
358
|
expected = pattern[key]
|
359
|
+
matching_values(actual, expected, content_type)
|
360
|
+
end
|
361
|
+
end
|
315
362
|
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
363
|
+
def matching_body_array?(query_parameters, pattern, content_type)
|
364
|
+
return false unless query_parameters.is_a?(Array)
|
365
|
+
return false unless query_parameters.length == pattern.length
|
366
|
+
|
367
|
+
query_parameters.each_with_index do |actual, index|
|
368
|
+
expected = pattern[index]
|
369
|
+
return false unless matching_values(actual, expected, content_type)
|
322
370
|
end
|
371
|
+
|
323
372
|
true
|
324
373
|
end
|
325
374
|
|
375
|
+
def matching_values(actual, expected, content_type)
|
376
|
+
return matching_body_hashes?(actual, expected, content_type) if actual.is_a?(Hash) && expected.is_a?(Hash)
|
377
|
+
return matching_body_array?(actual, expected, content_type) if actual.is_a?(Array) && expected.is_a?(Array)
|
378
|
+
|
379
|
+
expected = WebMock::Util::ValuesStringifier.stringify_values(expected) if url_encoded_body?(content_type)
|
380
|
+
expected === actual
|
381
|
+
end
|
382
|
+
|
326
383
|
def empty_string?(string)
|
327
384
|
string.nil? || string == ""
|
328
385
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module WebMock
|
2
4
|
|
3
5
|
class RequestSignature
|
@@ -35,11 +37,11 @@ module WebMock
|
|
35
37
|
alias == eql?
|
36
38
|
|
37
39
|
def url_encoded?
|
38
|
-
!!(headers
|
40
|
+
!!(headers&.fetch('Content-Type', nil)&.start_with?('application/x-www-form-urlencoded'))
|
39
41
|
end
|
40
42
|
|
41
43
|
def json_headers?
|
42
|
-
!!(headers
|
44
|
+
!!(headers&.fetch('Content-Type', nil)&.start_with?('application/json'))
|
43
45
|
end
|
44
46
|
|
45
47
|
private
|
data/lib/webmock/request_stub.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module WebMock
|
2
4
|
class RequestStub
|
3
5
|
|
@@ -24,6 +26,38 @@ module WebMock
|
|
24
26
|
end
|
25
27
|
alias_method :and_return, :to_return
|
26
28
|
|
29
|
+
def to_return_json(*response_hashes)
|
30
|
+
raise ArgumentError, '#to_return_json does not support passing a block' if block_given?
|
31
|
+
|
32
|
+
json_response_hashes = [*response_hashes].flatten.map do |resp_h|
|
33
|
+
headers, body = resp_h.values_at(:headers, :body)
|
34
|
+
|
35
|
+
json_body = if body.respond_to?(:call)
|
36
|
+
->(request_signature) {
|
37
|
+
b = if body.respond_to?(:arity) && body.arity == 1
|
38
|
+
body.call(request_signature)
|
39
|
+
else
|
40
|
+
body.call
|
41
|
+
end
|
42
|
+
b = b.to_json unless b.is_a?(String)
|
43
|
+
b
|
44
|
+
}
|
45
|
+
elsif !body.is_a?(String)
|
46
|
+
body.to_json
|
47
|
+
else
|
48
|
+
body
|
49
|
+
end
|
50
|
+
|
51
|
+
resp_h.merge(
|
52
|
+
headers: {content_type: 'application/json'}.merge(headers.to_h),
|
53
|
+
body: json_body
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
to_return(json_response_hashes)
|
58
|
+
end
|
59
|
+
alias_method :and_return_json, :to_return_json
|
60
|
+
|
27
61
|
def to_rack(app, options={})
|
28
62
|
@responses_sequences << ResponsesSequence.new([RackResponse.new(app)])
|
29
63
|
end
|
data/lib/webmock/response.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "pathname"
|
2
4
|
|
3
5
|
module WebMock
|
@@ -14,8 +16,11 @@ module WebMock
|
|
14
16
|
|
15
17
|
class Response
|
16
18
|
def initialize(options = {})
|
17
|
-
|
19
|
+
case options
|
20
|
+
when IO, StringIO
|
18
21
|
self.options = read_raw_response(options)
|
22
|
+
when String
|
23
|
+
self.options = read_raw_response(StringIO.new(options))
|
19
24
|
else
|
20
25
|
self.options = options
|
21
26
|
end
|
@@ -33,7 +38,7 @@ module WebMock
|
|
33
38
|
end
|
34
39
|
|
35
40
|
def body
|
36
|
-
@body ||
|
41
|
+
@body || String.new("")
|
37
42
|
end
|
38
43
|
|
39
44
|
def body=(body)
|
@@ -91,10 +96,10 @@ module WebMock
|
|
91
96
|
|
92
97
|
def ==(other)
|
93
98
|
self.body == other.body &&
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
99
|
+
self.headers === other.headers &&
|
100
|
+
self.status == other.status &&
|
101
|
+
self.exception == other.exception &&
|
102
|
+
self.should_timeout == other.should_timeout
|
98
103
|
end
|
99
104
|
|
100
105
|
private
|
@@ -111,16 +116,17 @@ module WebMock
|
|
111
116
|
valid_types = [Proc, IO, Pathname, String, Array]
|
112
117
|
return if @body.nil?
|
113
118
|
return if valid_types.any? { |c| @body.is_a?(c) }
|
114
|
-
raise InvalidBody, "must be one of: #{valid_types}. '#{@body.class}' given"
|
115
|
-
end
|
116
119
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
120
|
+
if @body.is_a?(Hash)
|
121
|
+
raise InvalidBody, "must be one of: #{valid_types}, but you've used a #{@body.class}. " \
|
122
|
+
"Please convert it by calling .to_json .to_xml, or otherwise convert it to a string."
|
123
|
+
else
|
124
|
+
raise InvalidBody, "must be one of: #{valid_types}. '#{@body.class}' given."
|
122
125
|
end
|
123
|
-
|
126
|
+
end
|
127
|
+
|
128
|
+
def read_raw_response(io)
|
129
|
+
socket = ::Net::BufferedIO.new(io)
|
124
130
|
response = ::Net::HTTPResponse.read_new(socket)
|
125
131
|
transfer_encoding = response.delete('transfer-encoding') #chunks were already read by curl
|
126
132
|
response.reading_body(socket, true) {}
|
@@ -132,6 +138,8 @@ module WebMock
|
|
132
138
|
options[:body] = response.read_body
|
133
139
|
options[:status] = [response.code.to_i, response.message]
|
134
140
|
options
|
141
|
+
ensure
|
142
|
+
socket.close
|
135
143
|
end
|
136
144
|
|
137
145
|
InvalidBody = Class.new(StandardError)
|
data/lib/webmock/rspec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'webmock'
|
2
4
|
|
3
5
|
# RSpec 1.x and 2.x compatibility
|
@@ -33,7 +35,8 @@ RSPEC_CONFIGURER.configure { |config|
|
|
33
35
|
WebMock.disable!
|
34
36
|
end
|
35
37
|
|
36
|
-
config.
|
38
|
+
config.around(:each) do |example|
|
39
|
+
example.run
|
37
40
|
WebMock.reset!
|
38
41
|
end
|
39
42
|
}
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module WebMock
|
2
4
|
|
3
5
|
class StubRegistry
|
@@ -10,25 +12,39 @@ module WebMock
|
|
10
12
|
end
|
11
13
|
|
12
14
|
def global_stubs
|
13
|
-
@global_stubs ||= []
|
15
|
+
@global_stubs ||= Hash.new { |h, k| h[k] = [] }
|
14
16
|
end
|
15
17
|
|
16
18
|
def reset!
|
17
19
|
self.request_stubs = []
|
18
20
|
end
|
19
21
|
|
20
|
-
def register_global_stub(&block)
|
22
|
+
def register_global_stub(order = :before_local_stubs, &block)
|
23
|
+
unless %i[before_local_stubs after_local_stubs].include?(order)
|
24
|
+
raise ArgumentError.new("Wrong order. Use :before_local_stubs or :after_local_stubs")
|
25
|
+
end
|
26
|
+
|
21
27
|
# This hash contains the responses returned by the block,
|
22
28
|
# keyed by the exact request (using the object_id).
|
23
29
|
# That way, there's no race condition in case #to_return
|
24
30
|
# doesn't run immediately after stub.with.
|
25
31
|
responses = {}
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
response_lock = Mutex.new
|
33
|
+
|
34
|
+
stub = ::WebMock::RequestStub.new(:any, ->(uri) { true }).with { |request|
|
35
|
+
update_response = -> { responses[request.object_id] = yield(request) }
|
36
|
+
|
37
|
+
# The block can recurse, so only lock if we don't already own it
|
38
|
+
if response_lock.owned?
|
39
|
+
update_response.call
|
40
|
+
else
|
41
|
+
response_lock.synchronize(&update_response)
|
42
|
+
end
|
43
|
+
}.to_return(lambda { |request|
|
44
|
+
response_lock.synchronize { responses.delete(request.object_id) }
|
45
|
+
})
|
46
|
+
|
47
|
+
global_stubs[order].push stub
|
32
48
|
end
|
33
49
|
|
34
50
|
def register_request_stub(stub)
|
@@ -54,9 +70,10 @@ module WebMock
|
|
54
70
|
private
|
55
71
|
|
56
72
|
def request_stub_for(request_signature)
|
57
|
-
(global_stubs + request_stubs
|
58
|
-
registered_request_stub
|
59
|
-
|
73
|
+
(global_stubs[:before_local_stubs] + request_stubs + global_stubs[:after_local_stubs])
|
74
|
+
.detect { |registered_request_stub|
|
75
|
+
registered_request_stub.request_pattern.matches?(request_signature)
|
76
|
+
}
|
60
77
|
end
|
61
78
|
|
62
79
|
def evaluate_response_for_request(response, request_signature)
|
data/lib/webmock/test_unit.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test/unit'
|
2
4
|
require 'webmock'
|
3
5
|
|
@@ -8,12 +10,10 @@ module Test
|
|
8
10
|
class TestCase
|
9
11
|
include WebMock::API
|
10
12
|
|
11
|
-
|
13
|
+
teardown
|
12
14
|
def teardown_with_webmock
|
13
|
-
teardown_without_webmock
|
14
15
|
WebMock.reset!
|
15
16
|
end
|
16
|
-
alias_method :teardown, :teardown_with_webmock
|
17
17
|
|
18
18
|
end
|
19
19
|
end
|
@@ -1,29 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'thread'
|
2
4
|
|
3
5
|
module WebMock
|
4
6
|
module Util
|
5
7
|
class HashCounter
|
6
8
|
attr_accessor :hash
|
9
|
+
|
7
10
|
def initialize
|
8
|
-
self.hash =
|
11
|
+
self.hash = Hash.new(0)
|
9
12
|
@order = {}
|
10
13
|
@max = 0
|
11
14
|
@lock = ::Mutex.new
|
12
15
|
end
|
13
|
-
|
16
|
+
|
17
|
+
def put(key, num=1)
|
14
18
|
@lock.synchronize do
|
15
|
-
hash[key]
|
16
|
-
@order[key] = @max
|
19
|
+
hash[key] += num
|
20
|
+
@order[key] = @max += 1
|
17
21
|
end
|
18
22
|
end
|
19
|
-
|
23
|
+
|
24
|
+
def get(key)
|
20
25
|
@lock.synchronize do
|
21
|
-
hash[key]
|
26
|
+
hash[key]
|
22
27
|
end
|
23
28
|
end
|
24
29
|
|
25
30
|
def select(&block)
|
26
31
|
return unless block_given?
|
32
|
+
|
27
33
|
@lock.synchronize do
|
28
34
|
hash.select(&block)
|
29
35
|
end
|