webmock 3.6.2 → 3.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d54455d6752d60f630b108721f21ad51f4d2e648cf1fe492f72cce5d0e3bd66
4
- data.tar.gz: 937d29ecd33fe244fe5f9749140d94c4ea68134b8afdcdd44a4ec41d5562df10
3
+ metadata.gz: e385b4f3b881b29e228d1b6517f4f7a119fbde52757c0076a1be4ad97fb7c860
4
+ data.tar.gz: ed890699362b956dd2f3e8707d33377069064183355015a6bc7d4fdfbc1d94b9
5
5
  SHA512:
6
- metadata.gz: 46ffed006b40f5d04d66ca5c3997f5874801e55d50a6580c1f3686a1c06a2fd4f69b4ab23c07f4828bdf01ace8749a0a7874a92db04780e621333a731bf89baf
7
- data.tar.gz: 3d265897b59b5adcf8cf1954c5656160eb8bfeeb583d3abdcf9883b61b88b1b09ed050da8f45f582a190a86beb8d1bb809d55b39d89ac9ab4ed1681bc05ebeaa
6
+ metadata.gz: 93519997dde799f24eb9f64412b5c49ff2b1444fe0158ead76cbf9d340d0273f63aa6790e3acaf5b621df08df621d85d7b3c6a50b55f0d82494869fdac5e491a
7
+ data.tar.gz: 8668e895d819594f52963336a376c3b0a6b857eccc557d42f5d0d71757ed64af02efd10275c494b2c64b577b81e7f454017ecd5a5b50f4946e817979162521ef
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.7.0
4
+
5
+ * Support for Async::HTTP::Client
6
+
7
+ Thanks to [Andriy Yanko](https://github.com/ayanko)
8
+
3
9
  ## 3.6.2
4
10
 
5
11
  * Fixed Patron adapter to handle HTTP/2 status line.
data/README.md CHANGED
@@ -33,6 +33,7 @@ Supported HTTP libraries
33
33
  * Excon
34
34
  * HTTP Gem
35
35
  * Manticore
36
+ * Async::HTTP::Client
36
37
 
37
38
  Supported Ruby Interpreters
38
39
  ---------------------------
@@ -1105,8 +1106,7 @@ People who submitted patches and new features or suggested improvements. Many th
1105
1106
  * Csaba Apagyi
1106
1107
  * Frederick Cheung
1107
1108
  * Fábio D. Batista
1108
-
1109
-
1109
+ * Andriy Yanko
1110
1110
 
1111
1111
 
1112
1112
  For a full list of contributors you can visit the
@@ -54,5 +54,6 @@ require_relative 'webmock/http_lib_adapters/em_http_request_adapter'
54
54
  require_relative 'webmock/http_lib_adapters/typhoeus_hydra_adapter'
55
55
  require_relative 'webmock/http_lib_adapters/excon_adapter'
56
56
  require_relative 'webmock/http_lib_adapters/manticore_adapter'
57
+ require_relative 'webmock/http_lib_adapters/async_http_client_adapter'
57
58
 
58
59
  require_relative 'webmock/webmock'
@@ -0,0 +1,214 @@
1
+ begin
2
+ require 'async'
3
+ require 'async/http'
4
+ rescue LoadError
5
+ # async-http not found
6
+ end
7
+
8
+ if defined?(Async::HTTP)
9
+ module WebMock
10
+ module HttpLibAdapters
11
+ class AsyncHttpClientAdapter < HttpLibAdapter
12
+ adapter_for :async_http_client
13
+
14
+ OriginalAsyncHttpClient = Async::HTTP::Client unless const_defined?(:OriginalAsyncHttpClient)
15
+
16
+ class << self
17
+ def enable!
18
+ Async::HTTP.send(:remove_const, :Client)
19
+ Async::HTTP.send(:const_set, :Client, Async::HTTP::WebMockClientWrapper)
20
+ end
21
+
22
+ def disable!
23
+ Async::HTTP.send(:remove_const, :Client)
24
+ Async::HTTP.send(:const_set, :Client, OriginalAsyncHttpClient)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ module Async
32
+ module HTTP
33
+ class WebMockClientWrapper < Client
34
+ def initialize(
35
+ endpoint,
36
+ protocol = endpoint.protocol,
37
+ scheme = endpoint.scheme,
38
+ authority = endpoint.authority,
39
+ options = {}
40
+ )
41
+ webmock_endpoint = WebMockEndpoint.new(scheme, authority, protocol)
42
+
43
+ @network_client = WebMockClient.new(endpoint, protocol, scheme, authority, options)
44
+ @webmock_client = WebMockClient.new(webmock_endpoint, protocol, scheme, authority, options)
45
+
46
+ @scheme = scheme
47
+ @authority = authority
48
+ end
49
+
50
+ def call(request)
51
+ request.scheme ||= self.scheme
52
+ request.authority ||= self.authority
53
+
54
+ request_signature = build_request_signature(request)
55
+ WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
56
+ webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
57
+ net_connect_allowed = WebMock.net_connect_allowed?(request_signature.uri)
58
+
59
+ if webmock_response
60
+ webmock_response.raise_error_if_any
61
+ raise Async::TimeoutError, 'WebMock timeout error' if webmock_response.should_timeout
62
+ WebMockApplication.add_webmock_response(request, webmock_response)
63
+ response = @webmock_client.call(request)
64
+ elsif net_connect_allowed
65
+ response = @network_client.call(request)
66
+ else
67
+ raise WebMock::NetConnectNotAllowedError.new(request_signature) unless webmock_response
68
+ end
69
+
70
+ if WebMock::CallbackRegistry.any_callbacks?
71
+ webmock_response ||= build_webmock_response(response)
72
+ WebMock::CallbackRegistry.invoke_callbacks(
73
+ {
74
+ lib: :async_http_client,
75
+ real_request: net_connect_allowed
76
+ },
77
+ request_signature,
78
+ webmock_response
79
+ )
80
+ end
81
+
82
+ response
83
+ end
84
+
85
+ def close
86
+ @network_client.close
87
+ @webmock_client.close
88
+ end
89
+
90
+ private
91
+
92
+ def build_request_signature(request)
93
+ body = request.read
94
+ request.body = ::Protocol::HTTP::Body::Buffered.wrap(body)
95
+ WebMock::RequestSignature.new(
96
+ request.method.downcase.to_sym,
97
+ "#{request.scheme}://#{request.authority}#{request.path}",
98
+ headers: request.headers.to_h,
99
+ body: body
100
+ )
101
+ end
102
+
103
+ def build_webmock_response(response)
104
+ body = response.read
105
+ response.body = ::Protocol::HTTP::Body::Buffered.wrap(body)
106
+
107
+ webmock_response = WebMock::Response.new
108
+ webmock_response.status = [
109
+ response.status,
110
+ ::Protocol::HTTP1::Reason::DESCRIPTIONS[response.status]
111
+ ]
112
+ webmock_response.headers = build_webmock_response_headers(response)
113
+ webmock_response.body = body
114
+ webmock_response
115
+ end
116
+
117
+ def build_webmock_response_headers(response)
118
+ response.headers.each.each_with_object({}) do |(k, v), o|
119
+ o[k] ||= []
120
+ o[k] << v
121
+ end
122
+ end
123
+ end
124
+
125
+ class WebMockClient < Client
126
+ end
127
+
128
+ class WebMockEndpoint
129
+ def initialize(scheme, authority, protocol)
130
+ @scheme = scheme
131
+ @authority = authority
132
+ @protocol = protocol
133
+ end
134
+
135
+ attr :scheme, :authority, :protocol
136
+
137
+ def connect
138
+ server_socket, client_socket = create_connected_sockets
139
+ Async do
140
+ accept_socket(server_socket)
141
+ end
142
+ client_socket
143
+ end
144
+
145
+ def inspect
146
+ "\#<#{self.class}> #{scheme}://#{authority} protocol=#{protocol}"
147
+ end
148
+
149
+ private
150
+
151
+ def create_connected_sockets
152
+ Async::IO::Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM).tap do |sockets|
153
+ sockets.each do |socket|
154
+ socket.instance_variable_set :@alpn_protocol, @alpn_protocol
155
+ socket.instance_eval do
156
+ def alpn_protocol
157
+ nil # means HTTP11 will be used for HTTPS
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+
164
+ def accept_socket(socket)
165
+ server = Async::HTTP::Server.new(WebMockApplication, self)
166
+ server.accept(socket, socket.remote_address)
167
+ end
168
+ end
169
+
170
+ module WebMockApplication
171
+ WEBMOCK_REQUEST_ID_HEADER = 'x-webmock-request-id'.freeze
172
+
173
+ class << self
174
+ def call(request)
175
+ request.read
176
+ webmock_response = get_webmock_response(request)
177
+ build_response(webmock_response)
178
+ end
179
+
180
+ def add_webmock_response(request, webmock_response)
181
+ webmock_request_id = request.object_id.to_s
182
+ request.headers.add(WEBMOCK_REQUEST_ID_HEADER, webmock_request_id)
183
+ webmock_responses[webmock_request_id] = webmock_response
184
+ end
185
+
186
+ def get_webmock_response(request)
187
+ webmock_request_id = request.headers[WEBMOCK_REQUEST_ID_HEADER][0]
188
+ webmock_responses.fetch(webmock_request_id)
189
+ end
190
+
191
+ private
192
+
193
+ def webmock_responses
194
+ @webmock_responses ||= {}
195
+ end
196
+
197
+ def build_response(webmock_response)
198
+ headers = (webmock_response.headers || {}).each_with_object([]) do |(k, v), o|
199
+ Array(v).each do |v|
200
+ o.push [k, v]
201
+ end
202
+ end
203
+
204
+ ::Protocol::HTTP::Response[
205
+ webmock_response.status[0],
206
+ headers,
207
+ webmock_response.body
208
+ ]
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
@@ -1,3 +1,3 @@
1
1
  module WebMock
2
- VERSION = '3.6.2' unless defined?(::WebMock::VERSION)
2
+ VERSION = '3.7.0' unless defined?(::WebMock::VERSION)
3
3
  end
@@ -0,0 +1,349 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'acceptance/webmock_shared'
4
+ require_relative './async_http_client_spec_helper'
5
+
6
+ require 'protocol/http/body/file'
7
+
8
+ Async.logger.debug! if ENV['ASYNC_LOGGER_DEBUG']
9
+
10
+ unless RUBY_PLATFORM =~ /java/
11
+ describe 'Async::HTTP::Client' do
12
+ include AsyncHttpClientSpecHelper
13
+
14
+ include_context "with WebMock",
15
+ :no_status_message,
16
+ :no_url_auth,
17
+ :no_content_length_header
18
+
19
+ it 'works' do
20
+ stub_request(:get, 'http://www.example.com')
21
+ expect(make_request(:get, 'http://www.example.com')).to eq(
22
+ status: 200,
23
+ headers: {},
24
+ body: nil
25
+ )
26
+ end
27
+
28
+ it 'works with request path' do
29
+ stub_request(:get, 'http://www.example.com/foo')
30
+ expect(make_request(:get, 'http://www.example.com/foo')).to eq(
31
+ status: 200,
32
+ headers: {},
33
+ body: nil
34
+ )
35
+ end
36
+
37
+ it 'works with request query' do
38
+ stub_request(:get, 'http://www.example.com/').with(
39
+ query: {
40
+ 'foo' => 'bar'
41
+ }
42
+ )
43
+ expect(make_request(:get, 'http://www.example.com/?foo=bar')).to eq(
44
+ status: 200,
45
+ headers: {},
46
+ body: nil
47
+ )
48
+ end
49
+
50
+ it 'works with request headers' do
51
+ stub_request(:get, 'http://www.example.com').with(
52
+ headers: {
53
+ 'X-Token' => 'Token'
54
+ }
55
+ )
56
+ expect(
57
+ make_request :get, 'http://www.example.com',
58
+ headers: {
59
+ 'X-Token' => 'Token'
60
+ }
61
+ ).to eq(
62
+ status: 200,
63
+ headers: {},
64
+ body: nil
65
+ )
66
+ end
67
+
68
+ it 'works with request body as text' do
69
+ stub_request(:post, 'http://www.example.com').with(
70
+ body: 'x'*10_000
71
+ )
72
+ expect(
73
+ make_request :post, 'http://www.example.com',
74
+ body: 'x'*10_000
75
+ ).to eq(
76
+ status: 200,
77
+ headers: {},
78
+ body: nil
79
+ )
80
+ end
81
+
82
+ it 'works with request body as file' do
83
+ stub_request(:post, "www.example.com").with(
84
+ body: File.read(__FILE__)
85
+ )
86
+ expect(
87
+ make_request :post, "http://www.example.com",
88
+ body: ::Protocol::HTTP::Body::File.open(__FILE__, block_size: 32)
89
+ ).to eq(
90
+ status: 200,
91
+ headers: {},
92
+ body: nil
93
+ )
94
+ end
95
+
96
+ it 'works with response status' do
97
+ stub_request(:get, 'http://www.example.com').to_return(
98
+ status: 400
99
+ )
100
+ expect(make_request(:get, 'http://www.example.com')).to eq(
101
+ status: 400,
102
+ headers: {},
103
+ body: nil
104
+ )
105
+ end
106
+
107
+ it 'works with response headers' do
108
+ stub_request(:get, 'http://www.example.com').to_return(
109
+ headers: {
110
+ 'X-Token' => 'TOKEN'
111
+ }
112
+ )
113
+ expect(make_request(:get, 'http://www.example.com')).to eq(
114
+ status: 200,
115
+ headers: {
116
+ 'x-token' => ['TOKEN']
117
+ },
118
+ body: nil
119
+ )
120
+ end
121
+
122
+ it 'works with response body' do
123
+ stub_request(:get, 'http://www.example.com').to_return(
124
+ body: 'abc'
125
+ )
126
+ expect(make_request(:get, 'http://www.example.com')).to eq(
127
+ status: 200,
128
+ headers: {},
129
+ body: 'abc'
130
+ )
131
+ end
132
+
133
+ it 'works with to_timeout' do
134
+ stub_request(:get, 'http://www.example.com').to_timeout
135
+ expect { make_request(:get, 'http://www.example.com') }.to raise_error Async::TimeoutError
136
+ end
137
+
138
+ context 'scheme and protocol' do
139
+ before do
140
+ stub_request(
141
+ :get, "#{scheme}://www.example.com"
142
+ ).and_return(
143
+ body: 'BODY'
144
+ )
145
+ end
146
+
147
+ subject do
148
+ make_request(:get, "#{scheme}://www.example.com", protocol: protocol)
149
+ end
150
+
151
+ shared_examples :common do
152
+ specify do
153
+ expect(subject).to eq(
154
+ status: 200,
155
+ headers: {},
156
+ body: 'BODY'
157
+ )
158
+ end
159
+ end
160
+
161
+ context 'http scheme' do
162
+ let(:scheme) { 'http' }
163
+
164
+ context 'default protocol' do
165
+ let(:protocol) { nil }
166
+
167
+ include_examples :common
168
+ end
169
+
170
+ context 'HTTP10 protocol' do
171
+ let(:protocol) { Async::HTTP::Protocol::HTTP10 }
172
+
173
+ include_examples :common
174
+ end
175
+
176
+ context 'HTTP11 protocol' do
177
+ let(:protocol) { Async::HTTP::Protocol::HTTP11 }
178
+
179
+ include_examples :common
180
+ end
181
+
182
+ context 'HTTP2 protocol' do
183
+ let(:protocol) { Async::HTTP::Protocol::HTTP2 }
184
+
185
+ include_examples :common
186
+ end
187
+ end
188
+
189
+ context 'https scheme' do
190
+ let(:scheme) { 'https' }
191
+
192
+ context 'default protocol' do
193
+ let(:protocol) { nil }
194
+
195
+ include_examples :common
196
+ end
197
+
198
+ context 'HTTP10 protocol' do
199
+ let(:protocol) { Async::HTTP::Protocol::HTTP10 }
200
+
201
+ include_examples :common
202
+ end
203
+
204
+ context 'HTTP11 protocol' do
205
+ let(:protocol) { Async::HTTP::Protocol::HTTP11 }
206
+
207
+ include_examples :common
208
+ end
209
+
210
+ context 'HTTP2 protocol' do
211
+ let(:protocol) { Async::HTTP::Protocol::HTTP2 }
212
+
213
+ include_examples :common
214
+ end
215
+
216
+ context 'HTTPS protocol' do
217
+ let(:protocol) { Async::HTTP::Protocol::HTTPS }
218
+
219
+ include_examples :common
220
+ end
221
+ end
222
+ end
223
+
224
+ context 'multiple requests' do
225
+ let(:endpoint) { Async::HTTP::Endpoint.parse('http://www.example.com') }
226
+ let(:requests_count) { 3 }
227
+
228
+ shared_examples :common do
229
+ before do
230
+ requests_count.times do |index|
231
+ stub_request(
232
+ :get, "http://www.example.com/foo#{index}"
233
+ ).to_return(
234
+ status: 200 + index,
235
+ headers: {'X-Token' => "foo#{index}"},
236
+ body: "FOO#{index}"
237
+ )
238
+ end
239
+ end
240
+
241
+ specify do
242
+ expect(subject).to eq(
243
+ 0 => {
244
+ status: 200,
245
+ headers: {'x-token' => ['foo0']},
246
+ body: 'FOO0'
247
+ },
248
+ 1 => {
249
+ status: 201,
250
+ headers: {'x-token' => ['foo1']},
251
+ body: 'FOO1'
252
+ },
253
+ 2 => {
254
+ status: 202,
255
+ headers: {'x-token' => ['foo2']},
256
+ body: 'FOO2'
257
+ }
258
+ )
259
+ end
260
+ end
261
+
262
+ context 'sequential' do
263
+ subject do
264
+ responses = {}
265
+ Async do |task|
266
+ Async::HTTP::Client.open(endpoint, protocol) do |client|
267
+ requests_count.times do |index|
268
+ response = client.get "/foo#{index}"
269
+ responses[index] = response_to_hash(response)
270
+ end
271
+ end
272
+ end
273
+ responses
274
+ end
275
+
276
+ context 'HTTP1 protocol' do
277
+ let(:protocol) { Async::HTTP::Protocol::HTTP1 }
278
+
279
+ include_examples :common
280
+ end
281
+
282
+ context 'HTTP2 protocol' do
283
+ let(:protocol) { Async::HTTP::Protocol::HTTP2 }
284
+
285
+ include_examples :common
286
+ end
287
+ end
288
+
289
+ context 'asynchronous' do
290
+ subject do
291
+ responses = {}
292
+ Async do |task|
293
+ Async::HTTP::Client.open(endpoint, protocol) do |client|
294
+ tasks = requests_count.times.map do |index|
295
+ task.async do
296
+ response = client.get "/foo#{index}"
297
+ responses[index] = response_to_hash(response)
298
+ end
299
+ end
300
+
301
+ tasks.map(&:wait)
302
+ end
303
+ end
304
+ responses
305
+ end
306
+
307
+ context 'HTTP1 protocol' do
308
+ let(:protocol) { Async::HTTP::Protocol::HTTP1 }
309
+
310
+ include_examples :common
311
+ end
312
+
313
+ context 'HTTP2 protocol' do
314
+ let(:protocol) { Async::HTTP::Protocol::HTTP2 }
315
+
316
+ include_examples :common
317
+ end
318
+ end
319
+ end
320
+
321
+ def make_request(method, url, protocol: nil, headers: {}, body: nil)
322
+ Async do
323
+ endpoint = Async::HTTP::Endpoint.parse(url)
324
+
325
+ begin
326
+ Async::HTTP::Client.open(endpoint, protocol || endpoint.protocol) do |client|
327
+ response = client.send(
328
+ method,
329
+ endpoint.path,
330
+ headers,
331
+ body
332
+ )
333
+ response_to_hash(response)
334
+ end
335
+ rescue Async::TimeoutError => e
336
+ e
337
+ end
338
+ end.wait
339
+ end
340
+
341
+ def response_to_hash(response)
342
+ {
343
+ status: response.status,
344
+ headers: response.headers.to_h,
345
+ body: response.read
346
+ }
347
+ end
348
+ end
349
+ end
@@ -0,0 +1,73 @@
1
+ module AsyncHttpClientSpecHelper
2
+ def http_request(method, url, options = {}, &block)
3
+ endpoint = Async::HTTP::Endpoint.parse(url)
4
+
5
+ path = endpoint.path
6
+ path = path + "?" + options[:query] if options[:query]
7
+
8
+ headers = (options[:headers] || {}).each_with_object([]) do |(k, v), o|
9
+ Array(v).each do |v|
10
+ o.push [k, v]
11
+ end
12
+ end
13
+ headers.push(
14
+ ['authorization', 'Basic ' + Base64.strict_encode64(options[:basic_auth].join(':'))]
15
+ ) if options[:basic_auth]
16
+
17
+ body = options[:body]
18
+
19
+ Async do
20
+ begin
21
+ Async::HTTP::Client.open(endpoint) do |client|
22
+ response = client.send(
23
+ method,
24
+ path,
25
+ headers,
26
+ body
27
+ )
28
+
29
+ OpenStruct.new(
30
+ build_hash_response(response)
31
+ )
32
+ end
33
+ rescue Exception => e
34
+ e
35
+ end
36
+ end.wait
37
+ end
38
+
39
+ def client_timeout_exception_class
40
+ Async::TimeoutError
41
+ end
42
+
43
+ def connection_refused_exception_class
44
+ Errno::ECONNREFUSED
45
+ end
46
+
47
+ def http_library
48
+ :async_http_client
49
+ end
50
+
51
+ private
52
+
53
+ def build_hash_response(response)
54
+ {
55
+
56
+ status: response.status.to_s,
57
+ message: Protocol::HTTP1::Reason::DESCRIPTIONS[response.status],
58
+ headers: build_response_headers(response),
59
+ body: response.read
60
+ }
61
+ end
62
+
63
+ def build_response_headers(response)
64
+ response.headers.each.each_with_object({}) do |(k, v), o|
65
+ o[k] ||= []
66
+ o[k] << v
67
+ end.tap do |o|
68
+ o.each do |k, v|
69
+ o[k] = v.join(', ')
70
+ end
71
+ end
72
+ end
73
+ end
@@ -111,7 +111,8 @@ shared_context "callbacks" do |*adapter_info|
111
111
  end
112
112
 
113
113
  it "should pass real response to callback with headers" do
114
- expect(@response.headers["Content-Length"]).to eq("11")
114
+ expect(@response.headers["X-Powered-By"]).to eq( "ASP.NET")
115
+ expect(@response.headers["Content-Length"]).to eq("11") unless adapter_info.include?(:no_content_length_header)
115
116
  end
116
117
 
117
118
  it "should pass response to callback with body" do
@@ -64,7 +64,10 @@ shared_context "declared responses" do |*adapter_info|
64
64
  it "should return response with declared headers" do
65
65
  stub_request(:get, "www.example.com").to_return(headers: SAMPLE_HEADERS)
66
66
  response = http_request(:get, "http://www.example.com/")
67
- expect(response.headers["Content-Length"]).to eq("8888")
67
+ expect(response.headers["Accept"]).to eq("application/json")
68
+ unless adapter_info.include?(:no_content_length_header)
69
+ expect(response.headers["Content-Length"]).to eq("8888")
70
+ end
68
71
  end
69
72
 
70
73
  it "should return response with declared headers even if there are multiple headers with the same key" do
@@ -171,13 +174,22 @@ shared_context "declared responses" do |*adapter_info|
171
174
  end
172
175
 
173
176
  it "should return recorded headers" do
174
- expect(@response.headers).to eq({
175
- "Date"=>"Sat, 23 Jan 2010 01:01:05 GMT",
176
- "Content-Type"=>"text/html; charset=UTF-8",
177
- "Content-Length"=>"419",
178
- "Connection"=>"Keep-Alive",
179
- "Accept"=>"image/jpeg, image/png"
180
- })
177
+ if adapter_info.include?(:no_content_length_header)
178
+ expect(@response.headers).to eq({
179
+ "Date"=>"Sat, 23 Jan 2010 01:01:05 GMT",
180
+ "Content-Type"=>"text/html; charset=UTF-8",
181
+ "Connection"=>"Keep-Alive",
182
+ "Accept"=>"image/jpeg, image/png"
183
+ })
184
+ else
185
+ expect(@response.headers).to eq({
186
+ "Date"=>"Sat, 23 Jan 2010 01:01:05 GMT",
187
+ "Content-Type"=>"text/html; charset=UTF-8",
188
+ "Content-Length"=>"419",
189
+ "Connection"=>"Keep-Alive",
190
+ "Accept"=>"image/jpeg, image/png"
191
+ })
192
+ end
181
193
  end
182
194
 
183
195
  it "should return recorded body" do
@@ -205,13 +217,22 @@ shared_context "declared responses" do |*adapter_info|
205
217
  end
206
218
 
207
219
  it "should return recorded headers" do
208
- expect(@response.headers).to eq({
209
- "Date"=>"Sat, 23 Jan 2010 01:01:05 GMT",
210
- "Content-Type"=>"text/html; charset=UTF-8",
211
- "Content-Length"=>"419",
212
- "Connection"=>"Keep-Alive",
213
- "Accept"=>"image/jpeg, image/png"
214
- })
220
+ if adapter_info.include?(:no_content_length_header)
221
+ expect(@response.headers).to eq({
222
+ "Date"=>"Sat, 23 Jan 2010 01:01:05 GMT",
223
+ "Content-Type"=>"text/html; charset=UTF-8",
224
+ "Connection"=>"Keep-Alive",
225
+ "Accept"=>"image/jpeg, image/png"
226
+ })
227
+ else
228
+ expect(@response.headers).to eq({
229
+ "Date"=>"Sat, 23 Jan 2010 01:01:05 GMT",
230
+ "Content-Type"=>"text/html; charset=UTF-8",
231
+ "Content-Length"=>"419",
232
+ "Connection"=>"Keep-Alive",
233
+ "Accept"=>"image/jpeg, image/png"
234
+ })
235
+ end
215
236
  end
216
237
 
217
238
  it "should return recorded body" do
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
33
33
  s.add_development_dependency 'em-http-request', '>= 1.0.2'
34
34
  s.add_development_dependency 'em-synchrony', '>= 1.0.0'
35
35
  s.add_development_dependency 'excon', '>= 0.27.5'
36
+ s.add_development_dependency 'async-http', '>= 0.48.0'
36
37
  s.add_development_dependency 'minitest', '>= 5.0.0'
37
38
  s.add_development_dependency 'test-unit', '>= 3.0.0'
38
39
  s.add_development_dependency 'rdoc', '> 3.5.0'
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.6.2
4
+ version: 3.7.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: 2019-07-31 00:00:00.000000000 Z
11
+ date: 2019-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -198,6 +198,20 @@ dependencies:
198
198
  - - ">="
199
199
  - !ruby/object:Gem::Version
200
200
  version: 0.27.5
201
+ - !ruby/object:Gem::Dependency
202
+ name: async-http
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ">="
206
+ - !ruby/object:Gem::Version
207
+ version: 0.48.0
208
+ type: :development
209
+ prerelease: false
210
+ version_requirements: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: 0.48.0
201
215
  - !ruby/object:Gem::Dependency
202
216
  name: minitest
203
217
  requirement: !ruby/object:Gem::Requirement
@@ -265,6 +279,7 @@ files:
265
279
  - lib/webmock/cucumber.rb
266
280
  - lib/webmock/deprecation.rb
267
281
  - lib/webmock/errors.rb
282
+ - lib/webmock/http_lib_adapters/async_http_client_adapter.rb
268
283
  - lib/webmock/http_lib_adapters/curb_adapter.rb
269
284
  - lib/webmock/http_lib_adapters/em_http_request_adapter.rb
270
285
  - lib/webmock/http_lib_adapters/excon_adapter.rb
@@ -318,6 +333,8 @@ files:
318
333
  - minitest/test_helper.rb
319
334
  - minitest/test_webmock.rb
320
335
  - minitest/webmock_spec.rb
336
+ - spec/acceptance/async_http_client/async_http_client_spec.rb
337
+ - spec/acceptance/async_http_client/async_http_client_spec_helper.rb
321
338
  - spec/acceptance/curb/curb_spec.rb
322
339
  - spec/acceptance/curb/curb_spec_helper.rb
323
340
  - spec/acceptance/em_http_request/em_http_request_spec.rb
@@ -409,6 +426,8 @@ signing_key:
409
426
  specification_version: 4
410
427
  summary: Library for stubbing HTTP requests in Ruby.
411
428
  test_files:
429
+ - spec/acceptance/async_http_client/async_http_client_spec.rb
430
+ - spec/acceptance/async_http_client/async_http_client_spec_helper.rb
412
431
  - spec/acceptance/curb/curb_spec.rb
413
432
  - spec/acceptance/curb/curb_spec_helper.rb
414
433
  - spec/acceptance/em_http_request/em_http_request_spec.rb