webmock 3.5.0 → 3.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -7
- data/CHANGELOG.md +62 -0
- data/README.md +27 -1
- data/Rakefile +0 -2
- data/lib/webmock.rb +1 -0
- data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +214 -0
- data/lib/webmock/http_lib_adapters/curb_adapter.rb +6 -1
- data/lib/webmock/http_lib_adapters/manticore_adapter.rb +9 -6
- data/lib/webmock/http_lib_adapters/net_http.rb +9 -11
- data/lib/webmock/http_lib_adapters/net_http_response.rb +1 -1
- data/lib/webmock/http_lib_adapters/patron_adapter.rb +1 -1
- data/lib/webmock/request_body_diff.rb +1 -1
- data/lib/webmock/request_pattern.rb +2 -3
- data/lib/webmock/util/query_mapper.rb +4 -2
- data/lib/webmock/util/uri.rb +3 -4
- data/lib/webmock/version.rb +1 -1
- data/lib/webmock/webmock.rb +5 -0
- data/spec/acceptance/async_http_client/async_http_client_spec.rb +349 -0
- data/spec/acceptance/async_http_client/async_http_client_spec_helper.rb +73 -0
- data/spec/acceptance/curb/curb_spec.rb +11 -0
- data/spec/acceptance/shared/callbacks.rb +2 -1
- data/spec/acceptance/shared/request_expectations.rb +7 -0
- data/spec/acceptance/shared/returning_declared_responses.rb +36 -15
- data/spec/acceptance/shared/stubbing_requests.rb +5 -0
- data/spec/support/webmock_server.rb +1 -0
- data/spec/unit/request_pattern_spec.rb +6 -1
- data/spec/unit/util/query_mapper_spec.rb +7 -0
- data/spec/unit/util/uri_spec.rb +64 -2
- data/spec/unit/webmock_spec.rb +8 -0
- data/webmock.gemspec +2 -3
- metadata +30 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e772b611e0179353d7187a2e24a4d2e4afb894c8fcf60c439cf13cd3e64fdbe8
|
4
|
+
data.tar.gz: 3de0ac09c6659b28c4ad2b9abb5fa69adc67e7e489c2c0979e84e826ee576c69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44c7fa0892f5f0e1c1331287081bd3df86272b0843aeb34de8ea73a859dc8fb7ec3be24c5cd0ca83ff5cb699eadd5966fa9711e030d9a382f2a418c8d661bcfc
|
7
|
+
data.tar.gz: 40e5a59b2189f8b19bf7eb4a034f08e1b657e54c8a6912b212852f402f60aaaee5897178e0c58db707db0c7ef9bc0aa6d28a5c72df83e43ce8f4846a5393c3a2
|
data/.travis.yml
CHANGED
@@ -3,19 +3,17 @@ before_install:
|
|
3
3
|
- gem update bundler
|
4
4
|
rvm:
|
5
5
|
- 2.3.8
|
6
|
-
- 2.4.
|
7
|
-
- 2.5.
|
8
|
-
- 2.6.
|
6
|
+
- 2.4.6
|
7
|
+
- 2.5.5
|
8
|
+
- 2.6.3
|
9
9
|
- rbx-2
|
10
10
|
- ruby-head
|
11
11
|
- jruby-9.1.17.0
|
12
|
-
- jruby-9.2.
|
12
|
+
- jruby-9.2.7.0
|
13
13
|
- jruby-head
|
14
|
+
jdk: openjdk8
|
14
15
|
matrix:
|
15
16
|
allow_failures:
|
16
17
|
- rvm: jruby-head
|
17
18
|
- rvm: ruby-head
|
18
19
|
- rvm: rbx-2
|
19
|
-
# Send builds to container-based infrastructure
|
20
|
-
# http://docs.travis-ci.com/user/workers/container-based-infrastructure/
|
21
|
-
sudo: false
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,67 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 3.7.1
|
4
|
+
|
5
|
+
* Fixed Async::HTTP::Client adapter code to not cause Ruby warning
|
6
|
+
|
7
|
+
Thanks to [y-yagi](https://github.com/y-yagi)
|
8
|
+
|
9
|
+
## 3.7.0
|
10
|
+
|
11
|
+
* Support for Async::HTTP::Client
|
12
|
+
|
13
|
+
Thanks to [Andriy Yanko](https://github.com/ayanko)
|
14
|
+
|
15
|
+
## 3.6.2
|
16
|
+
|
17
|
+
* Fixed Patron adapter to handle HTTP/2 status line.
|
18
|
+
|
19
|
+
Thanks to [Fábio D. Batista](https://github.com/fabiob)
|
20
|
+
|
21
|
+
## 3.6.1
|
22
|
+
|
23
|
+
* Fixed issue with matching Addressable::Template without a period in the domain
|
24
|
+
|
25
|
+
Thanks to [Eike Send](https://github.com/eikes)
|
26
|
+
|
27
|
+
* Support for `write_timeout` in Net::HTTP
|
28
|
+
|
29
|
+
Thanks to [Claudio Poli](https://github.com/masterkain)
|
30
|
+
|
31
|
+
* Fixed issue with handling urls with ":80" or ":443" in the path.
|
32
|
+
|
33
|
+
Thanks to [Csaba Apagyi](https://github.com/thisismydesign) for reporting and to [Frederick Cheung](https://github.com/fcheung) for fixing the issue.
|
34
|
+
|
35
|
+
## 3.6.0
|
36
|
+
|
37
|
+
* Compatibility with the latest version of hashdiff gem, with constant changed from HashDiff to Hashdiff
|
38
|
+
|
39
|
+
Thanks to [Jeff Felchner](https://github.com/jfelchner)
|
40
|
+
|
41
|
+
* Added a hint to the error message raised when `with` method is called without args or a block.
|
42
|
+
|
43
|
+
Thanks to [Adam Sokolnicki](https://github.com/asok)
|
44
|
+
|
45
|
+
* Resetting configured HTTP method in Curb adapter after each request
|
46
|
+
|
47
|
+
Thanks to [tiendo1011](https://github.com/tiendo1011)
|
48
|
+
|
49
|
+
* Added `WebMock.enable_net_connect!` as an alias for `WebMock.allow_net_connect!`
|
50
|
+
and `WebMock.disallow_net_connect!` as an alias for `WebMock.disable_net_connect!`
|
51
|
+
|
52
|
+
Thanks to [SoonKhen OwYong](https://github.com/owyongsk)
|
53
|
+
|
54
|
+
* Fixed handling of empty arrays as query params when using Faraday
|
55
|
+
|
56
|
+
Thanks to [Ryan Moret](https://github.com/rcmoret)
|
57
|
+
|
58
|
+
## 3.5.1
|
59
|
+
|
60
|
+
* Disabling TracePoint defined in Net::BufferedIO in case of exception being raised.
|
61
|
+
|
62
|
+
Thanks to [Koichi Sasada](https://github.com/ko1)
|
63
|
+
|
64
|
+
|
3
65
|
## 3.5.0
|
4
66
|
|
5
67
|
* Ruby 2.6.0 support
|
data/README.md
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
WebMock
|
2
2
|
=======
|
3
|
-
[![Gem Version](https://badge.fury.io/rb/webmock.svg)](http://badge.fury.io/rb/webmock)
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/webmock.svg)](http://badge.fury.io/rb/webmock)
|
4
|
+
[![Build Status](https://secure.travis-ci.org/bblimke/webmock.svg?branch=master)](http://travis-ci.org/bblimke/webmock)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/bblimke/webmock/badges/gpa.svg)](https://codeclimate.com/github/bblimke/webmock)
|
6
|
+
[![Mentioned in Awesome Ruby](https://awesome.re/mentioned-badge.svg)](https://github.com/markets/awesome-ruby)
|
7
|
+
[![Inline docs](http://inch-ci.org/github/bblimke/webmock.svg?branch=master)](http://inch-ci.org/github/bblimke/webmock)
|
8
|
+
[![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=webmock&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=webmock&package-manager=bundler&version-scheme=semver)
|
4
9
|
|
5
10
|
Library for stubbing and setting expectations on HTTP requests in Ruby.
|
6
11
|
|
@@ -28,6 +33,7 @@ Supported HTTP libraries
|
|
28
33
|
* Excon
|
29
34
|
* HTTP Gem
|
30
35
|
* Manticore
|
36
|
+
* Async::HTTP::Client
|
31
37
|
|
32
38
|
Supported Ruby Interpreters
|
33
39
|
---------------------------
|
@@ -36,6 +42,7 @@ Supported Ruby Interpreters
|
|
36
42
|
* MRI 2.3
|
37
43
|
* MRI 2.4
|
38
44
|
* MRI 2.5
|
45
|
+
* MRI 2.6
|
39
46
|
* JRuby
|
40
47
|
* Rubinius
|
41
48
|
|
@@ -872,6 +879,10 @@ end
|
|
872
879
|
|
873
880
|
Please submit them here [http://github.com/bblimke/webmock/issues](http://github.com/bblimke/webmock/issues)
|
874
881
|
|
882
|
+
## Issue triage [![Open Source Helpers](https://www.codetriage.com/bblimke/webmock/badges/users.svg)](https://www.codetriage.com/bblimke/webmock)
|
883
|
+
|
884
|
+
You can contribute by triaging issues which may include reproducing bug reports or asking for vital information, such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to webmock on CodeTriage](https://www.codetriage.com/bblimke/webmock).
|
885
|
+
|
875
886
|
## Suggestions
|
876
887
|
|
877
888
|
If you have any suggestions on how to improve WebMock please send an email to the mailing list [groups.google.com/group/webmock-users](http://groups.google.com/group/webmock-users)
|
@@ -1083,6 +1094,21 @@ People who submitted patches and new features or suggested improvements. Many th
|
|
1083
1094
|
* Olle Jonsson
|
1084
1095
|
* Pavel Rosický
|
1085
1096
|
* Geremia Taglialatela
|
1097
|
+
* Koichi Sasada
|
1098
|
+
* Yusuke Endoh
|
1099
|
+
* Grey Baker
|
1100
|
+
* SoonKhen OwYong
|
1101
|
+
* Pavel Valena
|
1102
|
+
* Adam Sokolnicki
|
1103
|
+
* Jeff Felchner
|
1104
|
+
* Eike Send
|
1105
|
+
* Claudio Poli
|
1106
|
+
* Csaba Apagyi
|
1107
|
+
* Frederick Cheung
|
1108
|
+
* Fábio D. Batista
|
1109
|
+
* Andriy Yanko
|
1110
|
+
* y-yagi
|
1111
|
+
|
1086
1112
|
|
1087
1113
|
For a full list of contributors you can visit the
|
1088
1114
|
[contributors](https://github.com/bblimke/webmock/contributors) page.
|
data/Rakefile
CHANGED
data/lib/webmock.rb
CHANGED
@@ -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, value), o|
|
199
|
+
Array(value).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
|
@@ -54,7 +54,6 @@ if defined?(Curl)
|
|
54
54
|
|
55
55
|
module Curl
|
56
56
|
class WebMockCurlEasy < Curl::Easy
|
57
|
-
|
58
57
|
def curb_or_webmock
|
59
58
|
request_signature = build_request_signature
|
60
59
|
WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
|
@@ -271,6 +270,8 @@ if defined?(Curl)
|
|
271
270
|
def perform
|
272
271
|
@webmock_method ||= :get
|
273
272
|
curb_or_webmock { super }
|
273
|
+
ensure
|
274
|
+
reset_webmock_method
|
274
275
|
end
|
275
276
|
|
276
277
|
def put_data= data
|
@@ -333,6 +334,10 @@ if defined?(Curl)
|
|
333
334
|
METHOD
|
334
335
|
end
|
335
336
|
|
337
|
+
def reset_webmock_method
|
338
|
+
@webmock_method = :get
|
339
|
+
end
|
340
|
+
|
336
341
|
def reset
|
337
342
|
instance_variable_set(:@body_str, nil)
|
338
343
|
super
|
@@ -50,19 +50,22 @@ if defined?(Manticore)
|
|
50
50
|
|
51
51
|
if webmock_response = registered_response_for(request_signature)
|
52
52
|
webmock_response.raise_error_if_any
|
53
|
-
manticore_response = generate_manticore_response(webmock_response)
|
54
|
-
|
53
|
+
manticore_response = generate_manticore_response(webmock_response)
|
54
|
+
manticore_response.on_success do
|
55
|
+
WebMock::CallbackRegistry.invoke_callbacks({lib: :manticore, real_request: false}, request_signature, webmock_response)
|
56
|
+
end
|
55
57
|
|
56
58
|
elsif real_request_allowed?(request_signature.uri)
|
57
|
-
manticore_response = Manticore::Response.new(self, request, context, &block)
|
58
|
-
|
59
|
-
|
59
|
+
manticore_response = Manticore::Response.new(self, request, context, &block)
|
60
|
+
manticore_response.on_complete do |completed_response|
|
61
|
+
webmock_response = generate_webmock_response(completed_response)
|
62
|
+
WebMock::CallbackRegistry.invoke_callbacks({lib: :manticore, real_request: true}, request_signature, webmock_response)
|
63
|
+
end
|
60
64
|
|
61
65
|
else
|
62
66
|
raise WebMock::NetConnectNotAllowedError.new(request_signature)
|
63
67
|
end
|
64
68
|
|
65
|
-
WebMock::CallbackRegistry.invoke_callbacks({lib: :manticore, real_request: real_request}, request_signature, webmock_response)
|
66
69
|
manticore_response
|
67
70
|
end
|
68
71
|
|