webmock 3.6.2 → 3.7.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: 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