webmock 3.14.0 → 3.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +124 -2
- data/README.md +46 -18
- 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 +8 -1
- data/lib/webmock/http_lib_adapters/curb_adapter.rb +4 -2
- data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +14 -6
- data/lib/webmock/http_lib_adapters/excon_adapter.rb +2 -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 +3 -3
- data/lib/webmock/http_lib_adapters/http_rb/request.rb +3 -1
- data/lib/webmock/http_lib_adapters/http_rb/response.rb +6 -1
- data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +6 -2
- data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +8 -2
- data/lib/webmock/http_lib_adapters/http_rb_adapter.rb +2 -0
- data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +2 -0
- data/lib/webmock/http_lib_adapters/manticore_adapter.rb +2 -0
- data/lib/webmock/http_lib_adapters/net_http.rb +24 -115
- data/lib/webmock/http_lib_adapters/net_http_response.rb +2 -0
- data/lib/webmock/http_lib_adapters/patron_adapter.rb +2 -0
- data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +2 -0
- 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 +2 -0
- data/lib/webmock/request_body_diff.rb +2 -0
- data/lib/webmock/request_execution_verifier.rb +2 -0
- data/lib/webmock/request_pattern.rb +26 -8
- 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 +10 -8
- 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 +2 -0
- data/lib/webmock/stub_registry.rb +2 -0
- data/lib/webmock/stub_request_snippet.rb +2 -0
- data/lib/webmock/test_unit.rb +2 -0
- 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 +22 -8
- data/lib/webmock/util/json.rb +2 -0
- data/lib/webmock/util/query_mapper.rb +2 -0
- data/lib/webmock/util/uri.rb +3 -1
- 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 +12 -0
- data/lib/webmock.rb +2 -0
- metadata +51 -183
- data/.gemtest +0 -0
- data/.github/workflows/CI.yml +0 -37
- data/.gitignore +0 -34
- data/.rspec-tm +0 -2
- data/Gemfile +0 -9
- data/Rakefile +0 -38
- data/minitest/test_helper.rb +0 -34
- data/minitest/test_webmock.rb +0 -9
- data/minitest/webmock_spec.rb +0 -60
- data/spec/acceptance/async_http_client/async_http_client_spec.rb +0 -375
- data/spec/acceptance/async_http_client/async_http_client_spec_helper.rb +0 -73
- data/spec/acceptance/curb/curb_spec.rb +0 -499
- data/spec/acceptance/curb/curb_spec_helper.rb +0 -147
- data/spec/acceptance/em_http_request/em_http_request_spec.rb +0 -462
- 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 -52
- data/spec/acceptance/http_rb/http_rb_spec.rb +0 -93
- 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 -107
- 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 -369
- 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 -148
- 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 -930
- data/spec/acceptance/shared/returning_declared_responses.rb +0 -409
- data/spec/acceptance/shared/stubbing_requests.rb +0 -678
- 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 -70
- 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 -736
- 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 -286
- 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 -157
- data/spec/unit/util/uri_spec.rb +0 -371
- data/spec/unit/util/version_checker_spec.rb +0 -65
- data/spec/unit/webmock_spec.rb +0 -60
- 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 -12
- data/webmock.gemspec +0 -54
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'net/http'
|
|
2
4
|
require 'net/https'
|
|
3
5
|
require 'stringio'
|
|
@@ -10,24 +12,19 @@ module WebMock
|
|
|
10
12
|
adapter_for :net_http
|
|
11
13
|
|
|
12
14
|
OriginalNetHTTP = Net::HTTP unless const_defined?(:OriginalNetHTTP)
|
|
13
|
-
OriginalNetBufferedIO = Net::BufferedIO unless const_defined?(:OriginalNetBufferedIO)
|
|
14
15
|
|
|
15
16
|
def self.enable!
|
|
16
|
-
Net.send(:remove_const, :BufferedIO)
|
|
17
17
|
Net.send(:remove_const, :HTTP)
|
|
18
18
|
Net.send(:remove_const, :HTTPSession)
|
|
19
19
|
Net.send(:const_set, :HTTP, @webMockNetHTTP)
|
|
20
20
|
Net.send(:const_set, :HTTPSession, @webMockNetHTTP)
|
|
21
|
-
Net.send(:const_set, :BufferedIO, Net::WebMockNetBufferedIO)
|
|
22
21
|
end
|
|
23
22
|
|
|
24
23
|
def self.disable!
|
|
25
|
-
Net.send(:remove_const, :BufferedIO)
|
|
26
24
|
Net.send(:remove_const, :HTTP)
|
|
27
25
|
Net.send(:remove_const, :HTTPSession)
|
|
28
26
|
Net.send(:const_set, :HTTP, OriginalNetHTTP)
|
|
29
27
|
Net.send(:const_set, :HTTPSession, OriginalNetHTTP)
|
|
30
|
-
Net.send(:const_set, :BufferedIO, OriginalNetBufferedIO)
|
|
31
28
|
|
|
32
29
|
#copy all constants from @webMockNetHTTP to original Net::HTTP
|
|
33
30
|
#in case any constants were added to @webMockNetHTTP instead of Net::HTTP
|
|
@@ -98,13 +95,8 @@ module WebMock
|
|
|
98
95
|
after_request.call(response)
|
|
99
96
|
}
|
|
100
97
|
if started?
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
else
|
|
104
|
-
start_with_connect_without_finish {
|
|
105
|
-
super_with_after_request.call
|
|
106
|
-
}
|
|
107
|
-
end
|
|
98
|
+
ensure_actual_connection
|
|
99
|
+
super_with_after_request.call
|
|
108
100
|
else
|
|
109
101
|
start_with_connect {
|
|
110
102
|
super_with_after_request.call
|
|
@@ -119,32 +111,33 @@ module WebMock
|
|
|
119
111
|
raise IOError, 'HTTP session already opened' if @started
|
|
120
112
|
if block_given?
|
|
121
113
|
begin
|
|
114
|
+
@socket = Net::HTTP.socket_type.new
|
|
122
115
|
@started = true
|
|
123
116
|
return yield(self)
|
|
124
117
|
ensure
|
|
125
118
|
do_finish
|
|
126
119
|
end
|
|
127
120
|
end
|
|
121
|
+
@socket = Net::HTTP.socket_type.new
|
|
128
122
|
@started = true
|
|
129
123
|
self
|
|
130
124
|
end
|
|
131
125
|
|
|
132
126
|
|
|
133
|
-
def
|
|
134
|
-
if
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
end
|
|
127
|
+
def ensure_actual_connection
|
|
128
|
+
if @socket.is_a?(StubSocket)
|
|
129
|
+
@socket&.close
|
|
130
|
+
@socket = nil
|
|
131
|
+
do_start
|
|
139
132
|
end
|
|
140
|
-
do_start
|
|
141
|
-
self
|
|
142
133
|
end
|
|
143
134
|
|
|
144
135
|
alias_method :start_with_connect, :start
|
|
145
136
|
|
|
146
137
|
def start(&block)
|
|
147
|
-
|
|
138
|
+
uri = Addressable::URI.parse(WebMock::NetHTTPUtility.get_uri(self))
|
|
139
|
+
|
|
140
|
+
if WebMock.net_http_connect_on_start?(uri)
|
|
148
141
|
super(&block)
|
|
149
142
|
else
|
|
150
143
|
start_without_connect(&block)
|
|
@@ -169,7 +162,7 @@ module WebMock
|
|
|
169
162
|
response.extend Net::WebMockHTTPResponse
|
|
170
163
|
|
|
171
164
|
if webmock_response.should_timeout
|
|
172
|
-
raise
|
|
165
|
+
raise Net::OpenTimeout, "execution expired"
|
|
173
166
|
end
|
|
174
167
|
|
|
175
168
|
webmock_response.raise_error_if_any
|
|
@@ -179,16 +172,6 @@ module WebMock
|
|
|
179
172
|
response
|
|
180
173
|
end
|
|
181
174
|
|
|
182
|
-
def timeout_exception
|
|
183
|
-
if defined?(Net::OpenTimeout)
|
|
184
|
-
# Ruby 2.x
|
|
185
|
-
Net::OpenTimeout
|
|
186
|
-
else
|
|
187
|
-
# Fallback, if things change
|
|
188
|
-
Timeout::Error
|
|
189
|
-
end
|
|
190
|
-
end
|
|
191
|
-
|
|
192
175
|
def build_webmock_response(net_http_response)
|
|
193
176
|
webmock_response = WebMock::Response.new
|
|
194
177
|
webmock_response.status = [
|
|
@@ -222,31 +205,21 @@ module WebMock
|
|
|
222
205
|
end
|
|
223
206
|
end
|
|
224
207
|
|
|
225
|
-
# patch for StringIO behavior in Ruby 2.2.3
|
|
226
|
-
# https://github.com/bblimke/webmock/issues/558
|
|
227
|
-
class PatchedStringIO < StringIO #:nodoc:
|
|
228
|
-
|
|
229
|
-
alias_method :orig_read_nonblock, :read_nonblock
|
|
230
|
-
|
|
231
|
-
def read_nonblock(size, *args, **kwargs)
|
|
232
|
-
args.reject! {|arg| !arg.is_a?(Hash)}
|
|
233
|
-
orig_read_nonblock(size, *args, **kwargs)
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
end
|
|
237
|
-
|
|
238
208
|
class StubSocket #:nodoc:
|
|
239
209
|
|
|
240
210
|
attr_accessor :read_timeout, :continue_timeout, :write_timeout
|
|
241
211
|
|
|
242
212
|
def initialize(*args)
|
|
213
|
+
@closed = false
|
|
243
214
|
end
|
|
244
215
|
|
|
245
216
|
def closed?
|
|
246
|
-
@closed
|
|
217
|
+
@closed
|
|
247
218
|
end
|
|
248
219
|
|
|
249
220
|
def close
|
|
221
|
+
@closed = true
|
|
222
|
+
nil
|
|
250
223
|
end
|
|
251
224
|
|
|
252
225
|
def readuntil(*args)
|
|
@@ -258,57 +231,13 @@ class StubSocket #:nodoc:
|
|
|
258
231
|
|
|
259
232
|
class StubIO
|
|
260
233
|
def setsockopt(*args); end
|
|
234
|
+
def peer_cert; end
|
|
235
|
+
def peeraddr; ["AF_INET", 443, "127.0.0.1", "127.0.0.1"] end
|
|
236
|
+
def ssl_version; "TLSv1.3" end
|
|
237
|
+
def cipher; ["TLS_AES_128_GCM_SHA256", "TLSv1.3", 128, 128] end
|
|
261
238
|
end
|
|
262
239
|
end
|
|
263
240
|
|
|
264
|
-
module Net #:nodoc: all
|
|
265
|
-
|
|
266
|
-
class WebMockNetBufferedIO < BufferedIO
|
|
267
|
-
def initialize(io, *args, **kwargs)
|
|
268
|
-
io = case io
|
|
269
|
-
when Socket, OpenSSL::SSL::SSLSocket, IO
|
|
270
|
-
io
|
|
271
|
-
when StringIO
|
|
272
|
-
PatchedStringIO.new(io.string)
|
|
273
|
-
when String
|
|
274
|
-
PatchedStringIO.new(io)
|
|
275
|
-
end
|
|
276
|
-
raise "Unable to create local socket" unless io
|
|
277
|
-
|
|
278
|
-
# Prior to 2.4.0 `BufferedIO` only takes a single argument (`io`) with no
|
|
279
|
-
# options. Here we pass through our full set of arguments only if we're
|
|
280
|
-
# on 2.4.0 or later, and use a simplified invocation otherwise.
|
|
281
|
-
if RUBY_VERSION >= '2.4.0'
|
|
282
|
-
super
|
|
283
|
-
else
|
|
284
|
-
super(io)
|
|
285
|
-
end
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
if RUBY_VERSION >= '2.6.0'
|
|
289
|
-
# https://github.com/ruby/ruby/blob/7d02441f0d6e5c9d0a73a024519eba4f69e36dce/lib/net/protocol.rb#L208
|
|
290
|
-
# Modified version of method from ruby, so that nil is always passed into orig_read_nonblock to avoid timeout
|
|
291
|
-
def rbuf_fill
|
|
292
|
-
case rv = @io.read_nonblock(BUFSIZE, nil, exception: false)
|
|
293
|
-
when String
|
|
294
|
-
return if rv.nil?
|
|
295
|
-
@rbuf << rv
|
|
296
|
-
rv.clear
|
|
297
|
-
return
|
|
298
|
-
when :wait_readable
|
|
299
|
-
@io.to_io.wait_readable(@read_timeout) or raise Net::ReadTimeout
|
|
300
|
-
when :wait_writable
|
|
301
|
-
@io.to_io.wait_writable(@read_timeout) or raise Net::ReadTimeout
|
|
302
|
-
when nil
|
|
303
|
-
raise EOFError, 'end of file reached'
|
|
304
|
-
end while true
|
|
305
|
-
end
|
|
306
|
-
end
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
end
|
|
310
|
-
|
|
311
|
-
|
|
312
241
|
module WebMock
|
|
313
242
|
module NetHTTPUtility
|
|
314
243
|
|
|
@@ -325,7 +254,6 @@ module WebMock
|
|
|
325
254
|
method = request.method.downcase.to_sym
|
|
326
255
|
|
|
327
256
|
headers = Hash[*request.to_hash.map {|k,v| [k, v]}.inject([]) {|r,x| r + x}]
|
|
328
|
-
validate_headers(headers)
|
|
329
257
|
|
|
330
258
|
if request.body_stream
|
|
331
259
|
body = request.body_stream.read
|
|
@@ -341,7 +269,7 @@ module WebMock
|
|
|
341
269
|
WebMock::RequestSignature.new(method, uri, body: request.body, headers: headers)
|
|
342
270
|
end
|
|
343
271
|
|
|
344
|
-
def self.get_uri(net_http, path)
|
|
272
|
+
def self.get_uri(net_http, path = nil)
|
|
345
273
|
protocol = net_http.use_ssl? ? "https" : "http"
|
|
346
274
|
|
|
347
275
|
hostname = net_http.address
|
|
@@ -350,25 +278,6 @@ module WebMock
|
|
|
350
278
|
"#{protocol}://#{hostname}:#{net_http.port}#{path}"
|
|
351
279
|
end
|
|
352
280
|
|
|
353
|
-
def self.validate_headers(headers)
|
|
354
|
-
# For Ruby versions < 2.3.0, if you make a request with headers that are symbols
|
|
355
|
-
# Net::HTTP raises a NoMethodError
|
|
356
|
-
#
|
|
357
|
-
# WebMock normalizes headers when creating a RequestSignature,
|
|
358
|
-
# and will update all headers from symbols to strings.
|
|
359
|
-
#
|
|
360
|
-
# This could create a false positive in a test suite with WebMock.
|
|
361
|
-
#
|
|
362
|
-
# So before this point, WebMock raises an ArgumentError if any of the headers are symbols
|
|
363
|
-
# instead of the cryptic NoMethodError "undefined method `split' ...` from Net::HTTP
|
|
364
|
-
if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.3.0')
|
|
365
|
-
header_as_symbol = headers.keys.find {|header| header.is_a? Symbol}
|
|
366
|
-
if header_as_symbol
|
|
367
|
-
raise ArgumentError.new("Net:HTTP does not accept headers as symbols")
|
|
368
|
-
end
|
|
369
|
-
end
|
|
370
|
-
end
|
|
371
|
-
|
|
372
281
|
def self.check_right_http_connection
|
|
373
282
|
@was_right_http_connection_loaded = defined?(RightHttpConnection)
|
|
374
283
|
end
|
data/lib/webmock/minitest.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WebMock
|
|
2
4
|
|
|
3
5
|
module RSpecMatcherDetector
|
|
@@ -281,7 +283,9 @@ module WebMock
|
|
|
281
283
|
if (@pattern).is_a?(Hash)
|
|
282
284
|
return true if @pattern.empty?
|
|
283
285
|
matching_body_hashes?(body_as_hash(body, content_type), @pattern, content_type)
|
|
284
|
-
elsif (@pattern).is_a?(
|
|
286
|
+
elsif (@pattern).is_a?(Array)
|
|
287
|
+
matching_body_array?(body_as_hash(body, content_type), @pattern, content_type)
|
|
288
|
+
elsif (@pattern).is_a?(WebMock::Matchers::HashArgumentMatcher)
|
|
285
289
|
@pattern == body_as_hash(body, content_type)
|
|
286
290
|
else
|
|
287
291
|
empty_string?(@pattern) && empty_string?(body) ||
|
|
@@ -344,19 +348,33 @@ module WebMock
|
|
|
344
348
|
def matching_body_hashes?(query_parameters, pattern, content_type)
|
|
345
349
|
return false unless query_parameters.is_a?(Hash)
|
|
346
350
|
return false unless query_parameters.keys.sort == pattern.keys.sort
|
|
347
|
-
|
|
351
|
+
|
|
352
|
+
query_parameters.all? do |key, actual|
|
|
348
353
|
expected = pattern[key]
|
|
354
|
+
matching_values(actual, expected, content_type)
|
|
355
|
+
end
|
|
356
|
+
end
|
|
349
357
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
358
|
+
def matching_body_array?(query_parameters, pattern, content_type)
|
|
359
|
+
return false unless query_parameters.is_a?(Array)
|
|
360
|
+
return false unless query_parameters.length == pattern.length
|
|
361
|
+
|
|
362
|
+
query_parameters.each_with_index do |actual, index|
|
|
363
|
+
expected = pattern[index]
|
|
364
|
+
return false unless matching_values(actual, expected, content_type)
|
|
356
365
|
end
|
|
366
|
+
|
|
357
367
|
true
|
|
358
368
|
end
|
|
359
369
|
|
|
370
|
+
def matching_values(actual, expected, content_type)
|
|
371
|
+
return matching_body_hashes?(actual, expected, content_type) if actual.is_a?(Hash) && expected.is_a?(Hash)
|
|
372
|
+
return matching_body_array?(actual, expected, content_type) if actual.is_a?(Array) && expected.is_a?(Array)
|
|
373
|
+
|
|
374
|
+
expected = WebMock::Util::ValuesStringifier.stringify_values(expected) if url_encoded_body?(content_type)
|
|
375
|
+
expected === actual
|
|
376
|
+
end
|
|
377
|
+
|
|
360
378
|
def empty_string?(string)
|
|
361
379
|
string.nil? || string == ""
|
|
362
380
|
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
|
|
@@ -120,13 +125,8 @@ module WebMock
|
|
|
120
125
|
end
|
|
121
126
|
end
|
|
122
127
|
|
|
123
|
-
def read_raw_response(
|
|
124
|
-
|
|
125
|
-
string = raw_response.read
|
|
126
|
-
raw_response.close
|
|
127
|
-
raw_response = string
|
|
128
|
-
end
|
|
129
|
-
socket = ::Net::BufferedIO.new(raw_response)
|
|
128
|
+
def read_raw_response(io)
|
|
129
|
+
socket = ::Net::BufferedIO.new(io)
|
|
130
130
|
response = ::Net::HTTPResponse.read_new(socket)
|
|
131
131
|
transfer_encoding = response.delete('transfer-encoding') #chunks were already read by curl
|
|
132
132
|
response.reading_body(socket, true) {}
|
|
@@ -138,6 +138,8 @@ module WebMock
|
|
|
138
138
|
options[:body] = response.read_body
|
|
139
139
|
options[:status] = [response.code.to_i, response.message]
|
|
140
140
|
options
|
|
141
|
+
ensure
|
|
142
|
+
socket.close
|
|
141
143
|
end
|
|
142
144
|
|
|
143
145
|
InvalidBody = Class.new(StandardError)
|
data/lib/webmock/rspec.rb
CHANGED
data/lib/webmock/test_unit.rb
CHANGED
|
@@ -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
|
data/lib/webmock/util/headers.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'base64'
|
|
2
4
|
|
|
3
5
|
module WebMock
|
|
@@ -6,18 +8,21 @@ module WebMock
|
|
|
6
8
|
|
|
7
9
|
class Headers
|
|
8
10
|
|
|
11
|
+
STANDARD_HEADER_DELIMITER = '-'.freeze
|
|
12
|
+
NONSTANDARD_HEADER_DELIMITER = '_'.freeze
|
|
13
|
+
JOIN = ', '.freeze
|
|
14
|
+
|
|
9
15
|
def self.normalize_headers(headers)
|
|
10
16
|
return nil unless headers
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
|
|
18
|
+
headers.each_with_object({}) do |(name, value), new_headers|
|
|
19
|
+
new_headers[normalize_name(name)] =
|
|
20
|
+
case value
|
|
14
21
|
when Regexp then value
|
|
15
|
-
when Array then (value.size == 1) ? value.first.to_s : value.map
|
|
22
|
+
when Array then (value.size == 1) ? value.first.to_s : value.map(&:to_s).sort
|
|
16
23
|
else value.to_s
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
Hash[*array.inject([]) {|r,x| r + x}]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
21
26
|
end
|
|
22
27
|
|
|
23
28
|
def self.sorted_headers_string(headers)
|
|
@@ -57,6 +62,15 @@ module WebMock
|
|
|
57
62
|
"Basic #{Base64.strict_encode64(credentials.join(':')).chomp}"
|
|
58
63
|
end
|
|
59
64
|
|
|
65
|
+
def self.normalize_name(name)
|
|
66
|
+
name
|
|
67
|
+
.to_s
|
|
68
|
+
.tr(NONSTANDARD_HEADER_DELIMITER, STANDARD_HEADER_DELIMITER)
|
|
69
|
+
.split(STANDARD_HEADER_DELIMITER)
|
|
70
|
+
.map!(&:capitalize)
|
|
71
|
+
.join(STANDARD_HEADER_DELIMITER)
|
|
72
|
+
end
|
|
73
|
+
|
|
60
74
|
end
|
|
61
75
|
|
|
62
76
|
end
|