webmock 3.16.2 → 3.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 438dab0f90920381d01009b8c75892ac83e46043e170c17e1dba5e46ca755c61
4
- data.tar.gz: a760f4b2399f465c62cf03268c13a7ae973900945ed0c4631e146c44f688a97d
3
+ metadata.gz: 70c0ad15601d48c3f413012ced7fde245d03fcc5d5bb7b609fd2ce89084b2589
4
+ data.tar.gz: 4575309d868350685b573d8929ce1836eb044b00fb862c1b9b266a73a1992e9f
5
5
  SHA512:
6
- metadata.gz: c8033597431b3e8ce43e60837d31f18d1ffa52c35079827e122a4616587f29b480b2340786c841bbe9f6b9390c5df08e9b84e933160412c8dc1d5c8a9b214f8b
7
- data.tar.gz: e0580a7b6b712073edf7d6c38fbf7b6df00a294aa9910f1de0e2de61535de67d07315b5d10f141d7e3387bf91aaee7ce6bb204d40190b5357b2120dc0d7d4427
6
+ metadata.gz: acba1ac0ec3d97c5eb244a84d1b8e895f13e9b3cfb1ca5ac4c0d5109eb7fcc508a3d1e51faa426bd31cb2509d61effed7c134119b5c05d128b3466ec3ee397c7
7
+ data.tar.gz: e8eb5385dd3d4fc9f02c541fbec1bc2c825e07445046b3bde50c471925728c08b1bb9aaf963d61fb44f5a38041f54964ab9fa89caef4cd16fd06fe6bb1ceca44
data/CHANGELOG.md CHANGED
@@ -1,14 +1,50 @@
1
1
  # Changelog
2
2
 
3
- # 3.16.2
3
+ # 3.18.0
4
+
5
+ * Net::BufferedIO is not replaced anymore.
6
+
7
+ Thanks to [Ray Zane](https://github.com/rzane)
8
+
9
+ * Simplified connection handing in Net::HTTP adapter.
10
+
11
+ Thanks to [Ray Zane](https://github.com/rzane)
4
12
 
5
- * Minimum required Ruby version is 2.0 again.
13
+ # 3.17.1
6
14
 
7
- # 3.16.1
15
+ * Fixed Syntax Error
16
+
17
+ Thanks to [Mark Spangler](https://github.com/mspangler)
18
+
19
+ # 3.17.0
8
20
 
9
21
  * Minimum required Ruby version is 2.3
10
22
 
11
- # 3.16.0
23
+ Thanks to [Go Sueyoshi](https://github.com/sue445)
24
+
25
+ * When using Net::HTTP, stubbed socket StubSocket#close and StubSocket#closed? behave more like the real sockets.
26
+
27
+ Thanks to [Ray Zane](https://github.com/rzane)
28
+
29
+ * Added `peeraddr`, `ssl_version` and `cipher` methods to stubbed sockets used by Net::HTTP.
30
+
31
+ Thanks to [Ray Zane](https://github.com/rzane)
32
+
33
+ * Added support for matching top-level array in JSON request body.
34
+
35
+ E.g.
36
+
37
+ ````
38
+ stub_request(:post, 'www.example.com').with(body: [{a: 1}])
39
+ ````
40
+
41
+ Thanks to [Cedric Sohrauer](https://github.com/cedrics)
42
+
43
+ # 3.16.2
44
+
45
+ * Minimum required Ruby version is 2.0.
46
+
47
+ # 3.16.0 (yanked)
12
48
 
13
49
  * Fix leaky file descriptors and reuse socket for persistent connections.
14
50
 
@@ -18,7 +54,11 @@
18
54
 
19
55
  Thanks to [Ray Zane](https://github.com/rzane)
20
56
 
21
- # 3.15.0
57
+ # 3.15.2
58
+
59
+ * Minimum required Ruby version is 2.0.
60
+
61
+ # 3.15.0 (yanked)
22
62
 
23
63
  * fixed async-http adapter on Windows
24
64
 
data/README.md CHANGED
@@ -1166,13 +1166,17 @@ People who submitted patches and new features or suggested improvements. Many th
1166
1166
  * Timmitry
1167
1167
  * Michael Fairley
1168
1168
  * Ray Zane
1169
+ * Go Sueyoshi
1170
+ * Cedric Sohrauer
1171
+ * Akira Matsuda
1172
+ * Mark Spangler
1169
1173
 
1170
1174
  For a full list of contributors you can visit the
1171
1175
  [contributors](https://github.com/bblimke/webmock/contributors) page.
1172
1176
 
1173
1177
  ## Background
1174
1178
 
1175
- Thank you Fakeweb! This library was inspired by [FakeWeb](http://fakeweb.rubyforge.org).
1179
+ Thank you Fakeweb! This library was inspired by [FakeWeb](https://github.com/chrisk/fakeweb).
1176
1180
  I imported some solutions from that project to WebMock. I also copied some code i.e Net:HTTP adapter.
1177
1181
  Fakeweb architecture unfortunately didn't allow me to extend it easily with the features I needed.
1178
1182
  I also preferred some things to work differently i.e request stub precedence.
@@ -10,24 +10,19 @@ module WebMock
10
10
  adapter_for :net_http
11
11
 
12
12
  OriginalNetHTTP = Net::HTTP unless const_defined?(:OriginalNetHTTP)
13
- OriginalNetBufferedIO = Net::BufferedIO unless const_defined?(:OriginalNetBufferedIO)
14
13
 
15
14
  def self.enable!
16
- Net.send(:remove_const, :BufferedIO)
17
15
  Net.send(:remove_const, :HTTP)
18
16
  Net.send(:remove_const, :HTTPSession)
19
17
  Net.send(:const_set, :HTTP, @webMockNetHTTP)
20
18
  Net.send(:const_set, :HTTPSession, @webMockNetHTTP)
21
- Net.send(:const_set, :BufferedIO, Net::WebMockNetBufferedIO)
22
19
  end
23
20
 
24
21
  def self.disable!
25
- Net.send(:remove_const, :BufferedIO)
26
22
  Net.send(:remove_const, :HTTP)
27
23
  Net.send(:remove_const, :HTTPSession)
28
24
  Net.send(:const_set, :HTTP, OriginalNetHTTP)
29
25
  Net.send(:const_set, :HTTPSession, OriginalNetHTTP)
30
- Net.send(:const_set, :BufferedIO, OriginalNetBufferedIO)
31
26
 
32
27
  #copy all constants from @webMockNetHTTP to original Net::HTTP
33
28
  #in case any constants were added to @webMockNetHTTP instead of Net::HTTP
@@ -72,74 +67,57 @@ module WebMock
72
67
  end
73
68
 
74
69
  def request(request, body = nil, &block)
70
+ return super unless started?
71
+
75
72
  request_signature = WebMock::NetHTTPUtility.request_signature_from_request(self, request, body)
76
73
 
77
74
  WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
78
75
 
79
76
  if webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
80
- @socket = Net::HTTP.socket_type.new
81
77
  WebMock::CallbackRegistry.invoke_callbacks(
82
78
  {lib: :net_http}, request_signature, webmock_response)
83
79
  build_net_http_response(webmock_response, &block)
84
80
  elsif WebMock.net_connect_allowed?(request_signature.uri)
85
81
  check_right_http_connection
86
- after_request = lambda do |response|
87
- if WebMock::CallbackRegistry.any_callbacks?
88
- webmock_response = build_webmock_response(response)
89
- WebMock::CallbackRegistry.invoke_callbacks(
90
- {lib: :net_http, real_request: true}, request_signature, webmock_response)
91
- end
92
- response.extend Net::WebMockHTTPResponse
93
- block.call response if block
94
- response
95
- end
96
- super_with_after_request = lambda {
97
- response = super(request, nil, &nil)
98
- after_request.call(response)
99
- }
100
- if started?
101
- ensure_actual_connection
102
- super_with_after_request.call
103
- else
104
- start_with_connect {
105
- super_with_after_request.call
106
- }
82
+ ensure_actually_connected
83
+
84
+ response = super(request, nil, &nil)
85
+
86
+ if WebMock::CallbackRegistry.any_callbacks?
87
+ WebMock::CallbackRegistry.invoke_callbacks(
88
+ {lib: :net_http, real_request: true},
89
+ request_signature,
90
+ build_webmock_response(response)
91
+ )
107
92
  end
93
+
94
+ response.extend Net::WebMockHTTPResponse
95
+ block.call response if block
96
+ response
108
97
  else
109
98
  raise WebMock::NetConnectNotAllowedError.new(request_signature)
110
99
  end
111
100
  end
112
101
 
113
- def start_without_connect
114
- raise IOError, 'HTTP session already opened' if @started
115
- if block_given?
116
- begin
117
- @socket = Net::HTTP.socket_type.new
118
- @started = true
119
- return yield(self)
120
- ensure
121
- do_finish
122
- end
123
- end
124
- @socket = Net::HTTP.socket_type.new
125
- @started = true
126
- self
127
- end
128
-
129
-
130
- def ensure_actual_connection
131
- do_start if @socket.is_a?(StubSocket)
132
- end
102
+ private
133
103
 
134
- alias_method :start_with_connect, :start
104
+ alias_method :actually_connect, :connect
135
105
 
136
- def start(&block)
106
+ def connect
137
107
  uri = Addressable::URI.parse(WebMock::NetHTTPUtility.get_uri(self))
138
108
 
139
109
  if WebMock.net_http_connect_on_start?(uri)
140
- super(&block)
110
+ super
141
111
  else
142
- start_without_connect(&block)
112
+ @socket = StubSocket.new
113
+ end
114
+ end
115
+
116
+ def ensure_actually_connected
117
+ if @socket.is_a?(StubSocket)
118
+ @socket&.close
119
+ @socket = nil
120
+ actually_connect
143
121
  end
144
122
  end
145
123
 
@@ -161,7 +139,7 @@ module WebMock
161
139
  response.extend Net::WebMockHTTPResponse
162
140
 
163
141
  if webmock_response.should_timeout
164
- raise timeout_exception, "execution expired"
142
+ raise Net::OpenTimeout, "execution expired"
165
143
  end
166
144
 
167
145
  webmock_response.raise_error_if_any
@@ -171,16 +149,6 @@ module WebMock
171
149
  response
172
150
  end
173
151
 
174
- def timeout_exception
175
- if defined?(Net::OpenTimeout)
176
- # Ruby 2.x
177
- Net::OpenTimeout
178
- else
179
- # Fallback, if things change
180
- Timeout::Error
181
- end
182
- end
183
-
184
152
  def build_webmock_response(net_http_response)
185
153
  webmock_response = WebMock::Response.new
186
154
  webmock_response.status = [
@@ -214,31 +182,21 @@ module WebMock
214
182
  end
215
183
  end
216
184
 
217
- # patch for StringIO behavior in Ruby 2.2.3
218
- # https://github.com/bblimke/webmock/issues/558
219
- class PatchedStringIO < StringIO #:nodoc:
220
-
221
- alias_method :orig_read_nonblock, :read_nonblock
222
-
223
- def read_nonblock(size, *args, **kwargs)
224
- args.reject! {|arg| !arg.is_a?(Hash)}
225
- orig_read_nonblock(size, *args, **kwargs)
226
- end
227
-
228
- end
229
-
230
185
  class StubSocket #:nodoc:
231
186
 
232
187
  attr_accessor :read_timeout, :continue_timeout, :write_timeout
233
188
 
234
189
  def initialize(*args)
190
+ @closed = false
235
191
  end
236
192
 
237
193
  def closed?
238
- @closed ||= true
194
+ @closed
239
195
  end
240
196
 
241
197
  def close
198
+ @closed = true
199
+ nil
242
200
  end
243
201
 
244
202
  def readuntil(*args)
@@ -251,57 +209,12 @@ class StubSocket #:nodoc:
251
209
  class StubIO
252
210
  def setsockopt(*args); end
253
211
  def peer_cert; end
212
+ def peeraddr; ["AF_INET", 443, "127.0.0.1", "127.0.0.1"] end
213
+ def ssl_version; "TLSv1.3" end
214
+ def cipher; ["TLS_AES_128_GCM_SHA256", "TLSv1.3", 128, 128] end
254
215
  end
255
216
  end
256
217
 
257
- module Net #:nodoc: all
258
-
259
- class WebMockNetBufferedIO < BufferedIO
260
- def initialize(io, *args, **kwargs)
261
- io = case io
262
- when Socket, OpenSSL::SSL::SSLSocket, IO
263
- io
264
- when StringIO
265
- PatchedStringIO.new(io.string)
266
- when String
267
- PatchedStringIO.new(io)
268
- end
269
- raise "Unable to create local socket" unless io
270
-
271
- # Prior to 2.4.0 `BufferedIO` only takes a single argument (`io`) with no
272
- # options. Here we pass through our full set of arguments only if we're
273
- # on 2.4.0 or later, and use a simplified invocation otherwise.
274
- if RUBY_VERSION >= '2.4.0'
275
- super
276
- else
277
- super(io)
278
- end
279
- end
280
-
281
- if RUBY_VERSION >= '2.6.0'
282
- # https://github.com/ruby/ruby/blob/7d02441f0d6e5c9d0a73a024519eba4f69e36dce/lib/net/protocol.rb#L208
283
- # Modified version of method from ruby, so that nil is always passed into orig_read_nonblock to avoid timeout
284
- def rbuf_fill
285
- case rv = @io.read_nonblock(BUFSIZE, nil, exception: false)
286
- when String
287
- return if rv.nil?
288
- @rbuf << rv
289
- rv.clear
290
- return
291
- when :wait_readable
292
- @io.to_io.wait_readable(@read_timeout) or raise Net::ReadTimeout
293
- when :wait_writable
294
- @io.to_io.wait_writable(@read_timeout) or raise Net::ReadTimeout
295
- when nil
296
- raise EOFError, 'end of file reached'
297
- end while true
298
- end
299
- end
300
- end
301
-
302
- end
303
-
304
-
305
218
  module WebMock
306
219
  module NetHTTPUtility
307
220
 
@@ -318,7 +231,6 @@ module WebMock
318
231
  method = request.method.downcase.to_sym
319
232
 
320
233
  headers = Hash[*request.to_hash.map {|k,v| [k, v]}.inject([]) {|r,x| r + x}]
321
- validate_headers(headers)
322
234
 
323
235
  if request.body_stream
324
236
  body = request.body_stream.read
@@ -343,25 +255,6 @@ module WebMock
343
255
  "#{protocol}://#{hostname}:#{net_http.port}#{path}"
344
256
  end
345
257
 
346
- def self.validate_headers(headers)
347
- # For Ruby versions < 2.3.0, if you make a request with headers that are symbols
348
- # Net::HTTP raises a NoMethodError
349
- #
350
- # WebMock normalizes headers when creating a RequestSignature,
351
- # and will update all headers from symbols to strings.
352
- #
353
- # This could create a false positive in a test suite with WebMock.
354
- #
355
- # So before this point, WebMock raises an ArgumentError if any of the headers are symbols
356
- # instead of the cryptic NoMethodError "undefined method `split' ...` from Net::HTTP
357
- if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.3.0')
358
- header_as_symbol = headers.keys.find {|header| header.is_a? Symbol}
359
- if header_as_symbol
360
- raise ArgumentError.new("Net:HTTP does not accept headers as symbols")
361
- end
362
- end
363
- end
364
-
365
258
  def self.check_right_http_connection
366
259
  @was_right_http_connection_loaded = defined?(RightHttpConnection)
367
260
  end
@@ -281,6 +281,8 @@ module WebMock
281
281
  if (@pattern).is_a?(Hash)
282
282
  return true if @pattern.empty?
283
283
  matching_body_hashes?(body_as_hash(body, content_type), @pattern, content_type)
284
+ elsif (@pattern).is_a?(Array)
285
+ matching_body_array?(body_as_hash(body, content_type), @pattern, content_type)
284
286
  elsif (@pattern).is_a?(WebMock::Matchers::HashIncludingMatcher)
285
287
  @pattern == body_as_hash(body, content_type)
286
288
  else
@@ -344,19 +346,33 @@ module WebMock
344
346
  def matching_body_hashes?(query_parameters, pattern, content_type)
345
347
  return false unless query_parameters.is_a?(Hash)
346
348
  return false unless query_parameters.keys.sort == pattern.keys.sort
347
- query_parameters.each do |key, actual|
349
+
350
+ query_parameters.all? do |key, actual|
348
351
  expected = pattern[key]
352
+ matching_values(actual, expected, content_type)
353
+ end
354
+ end
349
355
 
350
- if actual.is_a?(Hash) && expected.is_a?(Hash)
351
- return false unless matching_body_hashes?(actual, expected, content_type)
352
- else
353
- expected = WebMock::Util::ValuesStringifier.stringify_values(expected) if url_encoded_body?(content_type)
354
- return false unless expected === actual
355
- end
356
+ def matching_body_array?(query_parameters, pattern, content_type)
357
+ return false unless query_parameters.is_a?(Array)
358
+ return false unless query_parameters.length == pattern.length
359
+
360
+ query_parameters.each_with_index do |actual, index|
361
+ expected = pattern[index]
362
+ return false unless matching_values(actual, expected, content_type)
356
363
  end
364
+
357
365
  true
358
366
  end
359
367
 
368
+ def matching_values(actual, expected, content_type)
369
+ return matching_body_hashes?(actual, expected, content_type) if actual.is_a?(Hash) && expected.is_a?(Hash)
370
+ return matching_body_array?(actual, expected, content_type) if actual.is_a?(Array) && expected.is_a?(Array)
371
+
372
+ expected = WebMock::Util::ValuesStringifier.stringify_values(expected) if url_encoded_body?(content_type)
373
+ expected === actual
374
+ end
375
+
360
376
  def empty_string?(string)
361
377
  string.nil? || string == ""
362
378
  end
@@ -35,11 +35,11 @@ module WebMock
35
35
  alias == eql?
36
36
 
37
37
  def url_encoded?
38
- !!(headers && headers.fetch('Content-Type', "").start_with?('application/x-www-form-urlencoded'))
38
+ !!(headers&.fetch('Content-Type', nil)&.start_with?('application/x-www-form-urlencoded'))
39
39
  end
40
40
 
41
41
  def json_headers?
42
- !!(headers && headers.fetch('Content-Type', "").start_with?('application/json'))
42
+ !!(headers&.fetch('Content-Type', nil)&.start_with?('application/json'))
43
43
  end
44
44
 
45
45
  private
@@ -14,8 +14,11 @@ module WebMock
14
14
 
15
15
  class Response
16
16
  def initialize(options = {})
17
- if options.is_a?(IO) || options.is_a?(String)
17
+ case options
18
+ when IO, StringIO
18
19
  self.options = read_raw_response(options)
20
+ when String
21
+ self.options = read_raw_response(StringIO.new(options))
19
22
  else
20
23
  self.options = options
21
24
  end
@@ -120,13 +123,8 @@ module WebMock
120
123
  end
121
124
  end
122
125
 
123
- def read_raw_response(raw_response)
124
- if raw_response.is_a?(IO)
125
- string = raw_response.read
126
- raw_response.close
127
- raw_response = string
128
- end
129
- socket = ::Net::BufferedIO.new(raw_response)
126
+ def read_raw_response(io)
127
+ socket = ::Net::BufferedIO.new(io)
130
128
  response = ::Net::HTTPResponse.read_new(socket)
131
129
  transfer_encoding = response.delete('transfer-encoding') #chunks were already read by curl
132
130
  response.reading_body(socket, true) {}
@@ -138,6 +136,8 @@ module WebMock
138
136
  options[:body] = response.read_body
139
137
  options[:status] = [response.code.to_i, response.message]
140
138
  options
139
+ ensure
140
+ socket.close
141
141
  end
142
142
 
143
143
  InvalidBody = Class.new(StandardError)
@@ -1,3 +1,3 @@
1
1
  module WebMock
2
- VERSION = '3.16.2' unless defined?(::WebMock::VERSION)
2
+ VERSION = '3.18.0' unless defined?(::WebMock::VERSION)
3
3
  end
@@ -115,33 +115,16 @@ describe "Net:HTTP" do
115
115
  expect(Net::HTTP.start("www.example.com") { |http| http.request(req)}.body).to eq("abc")
116
116
  end
117
117
 
118
- it "raises an ArgumentError if passed headers as symbols if RUBY_VERSION < 2.3.0" do
118
+ it "raises an ArgumentError if passed headers as symbols" do
119
119
  uri = URI.parse("http://google.com/")
120
120
  http = Net::HTTP.new(uri.host, uri.port)
121
121
  request = Net::HTTP::Get.new(uri.request_uri)
122
+ request[:InvalidHeaderSinceItsASymbol] = "this will not be valid"
122
123
 
123
- # Net::HTTP calls downcase on header keys assigned with []=
124
- # In Ruby 1.8.7 symbols do not respond to downcase
125
- #
126
- # Meaning you can not assign header keys as symbols in ruby 1.8.7 using []=
127
- if :symbol.respond_to?(:downcase)
128
- request[:InvalidHeaderSinceItsASymbol] = "this will not be valid"
129
- else
130
- request.instance_eval do
131
- @header = request.to_hash.merge({InvalidHeaderSinceItsASymbol: "this will not be valid"})
132
- end
133
- end
134
-
135
- if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.3.0')
136
- expect do
137
- http.request(request)
138
- end.to raise_error ArgumentError, "Net:HTTP does not accept headers as symbols"
139
- else
140
- stub_http_request(:get, "google.com").with(headers: { InvalidHeaderSinceItsASymbol: "this will not be valid" })
141
- expect do
142
- http.request(request)
143
- end.not_to raise_error
144
- end
124
+ stub_http_request(:get, "google.com").with(headers: { InvalidHeaderSinceItsASymbol: "this will not be valid" })
125
+ expect do
126
+ http.request(request)
127
+ end.not_to raise_error
145
128
  end
146
129
 
147
130
  it "should handle multiple values for the same response header" do
@@ -213,6 +196,22 @@ describe "Net:HTTP" do
213
196
  end
214
197
  end
215
198
 
199
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0')
200
+ it "uses the StubSocket to provide IP address" do
201
+ Net::HTTP.start("example.com") do |http|
202
+ expect(http.ipaddr).to eq("127.0.0.1")
203
+ end
204
+ end
205
+ end
206
+
207
+ it "defines common socket methods" do
208
+ Net::HTTP.start("example.com") do |http|
209
+ socket = http.instance_variable_get(:@socket)
210
+ expect(socket.io.ssl_version).to eq("TLSv1.3")
211
+ expect(socket.io.cipher).to eq(["TLS_AES_128_GCM_SHA256", "TLSv1.3", 128, 128])
212
+ end
213
+ end
214
+
216
215
  describe "connecting on Net::HTTP.start" do
217
216
  before(:each) do
218
217
  @http = Net::HTTP.new('www.google.com', 443)
@@ -93,31 +93,29 @@ unless RUBY_PLATFORM =~ /java/
93
93
  @sess.copy("/abc", "/def")
94
94
  end
95
95
 
96
- if /^1\.9/ === RUBY_VERSION
97
- describe "handling encoding same way as patron" do
98
- around(:each) do |example|
99
- @encoding = Encoding.default_internal
100
- Encoding.default_internal = "UTF-8"
101
- example.run
102
- Encoding.default_internal = @encoding
103
- end
96
+ describe "handling encoding same way as patron" do
97
+ around(:each) do |example|
98
+ @encoding = Encoding.default_internal
99
+ Encoding.default_internal = "UTF-8"
100
+ example.run
101
+ Encoding.default_internal = @encoding
102
+ end
104
103
 
105
- it "should not encode body with default encoding" do
106
- stub_request(:get, "www.example.com").
107
- to_return(body: "Øl")
104
+ it "should not encode body with default encoding" do
105
+ stub_request(:get, "www.example.com").
106
+ to_return(body: "Øl")
108
107
 
109
- expect(@sess.get("").body.encoding).to eq(Encoding::ASCII_8BIT)
110
- expect(@sess.get("").inspectable_body.encoding).to eq(Encoding::UTF_8)
111
- end
108
+ expect(@sess.get("").body.encoding).to eq(Encoding::ASCII_8BIT)
109
+ expect(@sess.get("").inspectable_body.encoding).to eq(Encoding::UTF_8)
110
+ end
112
111
 
113
- it "should not encode body to default internal" do
114
- stub_request(:get, "www.example.com").
115
- to_return(headers: {'Content-Type' => 'text/html; charset=iso-8859-1'},
116
- body: "Øl".encode("iso-8859-1"))
112
+ it "should not encode body to default internal" do
113
+ stub_request(:get, "www.example.com").
114
+ to_return(headers: {'Content-Type' => 'text/html; charset=iso-8859-1'},
115
+ body: "Øl".encode("iso-8859-1"))
117
116
 
118
- expect(@sess.get("").body.encoding).to eq(Encoding::ASCII_8BIT)
119
- expect(@sess.get("").decoded_body.encoding).to eq(Encoding.default_internal)
120
- end
117
+ expect(@sess.get("").body.encoding).to eq(Encoding::ASCII_8BIT)
118
+ expect(@sess.get("").decoded_body.encoding).to eq(Encoding.default_internal)
121
119
  end
122
120
  end
123
121
  end
@@ -547,6 +547,18 @@ describe WebMock::RequestPattern do
547
547
  body: "{\"a\":\"1\",\"b\":\"five\",\"c\":{\"d\":[\"e\",\"f\"]}}"))
548
548
  end
549
549
 
550
+ it "should match if the request body has a top level array" do
551
+ expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: [{a: 1}])).
552
+ to match(WebMock::RequestSignature.new(:post, "www.example.com",
553
+ headers: {content_type: content_type}, body: "[{\"a\":1}]"))
554
+ end
555
+
556
+ it "should not match if the request body has a different top level array" do
557
+ expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: ["a", "b"])).
558
+ not_to match(WebMock::RequestSignature.new(:post, "www.example.com",
559
+ headers: {content_type: content_type}, body: "[\"a\", \"c\"]"))
560
+ end
561
+
550
562
  it "should not match when body is not json" do
551
563
  expect(WebMock::RequestPattern.new(:post, 'www.example.com', body: body_hash)).
552
564
  not_to match(WebMock::RequestSignature.new(:post, "www.example.com",
@@ -142,6 +142,34 @@ describe WebMock::Response do
142
142
  end
143
143
 
144
144
  describe "from raw response" do
145
+ describe "when input is a StringIO" do
146
+ before(:each) do
147
+ @io = StringIO.new(File.read(CURL_EXAMPLE_OUTPUT_PATH))
148
+ @response = WebMock::Response.new(@io)
149
+ end
150
+
151
+ it "should read status" do
152
+ expect(@response.status).to eq([202, "OK"])
153
+ end
154
+
155
+ it "should read headers" do
156
+ expect(@response.headers).to eq(
157
+ "Date"=>"Sat, 23 Jan 2010 01:01:05 GMT",
158
+ "Content-Type"=>"text/html; charset=UTF-8",
159
+ "Content-Length"=>"419",
160
+ "Connection"=>"Keep-Alive",
161
+ "Accept"=>"image/jpeg, image/png"
162
+ )
163
+ end
164
+
165
+ it "should read body" do
166
+ expect(@response.body.size).to eq(419)
167
+ end
168
+
169
+ it "should close IO" do
170
+ expect(@io).to be_closed
171
+ end
172
+ end
145
173
 
146
174
  describe "when input is IO" do
147
175
  before(:each) do
data/webmock.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ['Bartosz Blimke']
10
10
  s.email = ['bartosz.blimke@gmail.com']
11
- s.homepage = 'http://github.com/bblimke/webmock'
11
+ s.homepage = 'https://github.com/bblimke/webmock'
12
12
  s.summary = %q{Library for stubbing HTTP requests in Ruby.}
13
13
  s.description = %q{WebMock allows stubbing HTTP requests and setting expectations on HTTP requests.}
14
14
  s.license = "MIT"
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
21
21
  'wiki_uri' => 'https://github.com/bblimke/webmock/wiki'
22
22
  }
23
23
 
24
- s.required_ruby_version = '>= 2.0'
24
+ s.required_ruby_version = '>= 2.3'
25
25
 
26
26
  s.add_dependency 'addressable', '>= 2.8.0'
27
27
  s.add_dependency 'crack', '>= 0.3.2'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webmock
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.16.2
4
+ version: 3.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bartosz Blimke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-10 00:00:00.000000000 Z
11
+ date: 2022-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -416,14 +416,14 @@ files:
416
416
  - test/test_helper.rb
417
417
  - test/test_webmock.rb
418
418
  - webmock.gemspec
419
- homepage: http://github.com/bblimke/webmock
419
+ homepage: https://github.com/bblimke/webmock
420
420
  licenses:
421
421
  - MIT
422
422
  metadata:
423
423
  bug_tracker_uri: https://github.com/bblimke/webmock/issues
424
- changelog_uri: https://github.com/bblimke/webmock/blob/v3.16.2/CHANGELOG.md
425
- documentation_uri: https://www.rubydoc.info/gems/webmock/3.16.2
426
- source_code_uri: https://github.com/bblimke/webmock/tree/v3.16.2
424
+ changelog_uri: https://github.com/bblimke/webmock/blob/v3.18.0/CHANGELOG.md
425
+ documentation_uri: https://www.rubydoc.info/gems/webmock/3.18.0
426
+ source_code_uri: https://github.com/bblimke/webmock/tree/v3.18.0
427
427
  wiki_uri: https://github.com/bblimke/webmock/wiki
428
428
  post_install_message:
429
429
  rdoc_options: []
@@ -433,14 +433,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
433
433
  requirements:
434
434
  - - ">="
435
435
  - !ruby/object:Gem::Version
436
- version: '2.0'
436
+ version: '2.3'
437
437
  required_rubygems_version: !ruby/object:Gem::Requirement
438
438
  requirements:
439
439
  - - ">="
440
440
  - !ruby/object:Gem::Version
441
441
  version: '0'
442
442
  requirements: []
443
- rubygems_version: 3.1.2
443
+ rubygems_version: 3.0.3
444
444
  signing_key:
445
445
  specification_version: 4
446
446
  summary: Library for stubbing HTTP requests in Ruby.