webmock 3.5.1 → 3.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -7
  3. data/CHANGELOG.md +65 -0
  4. data/README.md +25 -1
  5. data/Rakefile +0 -2
  6. data/lib/webmock.rb +1 -0
  7. data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +214 -0
  8. data/lib/webmock/http_lib_adapters/curb_adapter.rb +6 -1
  9. data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +1 -1
  10. data/lib/webmock/http_lib_adapters/manticore_adapter.rb +9 -6
  11. data/lib/webmock/http_lib_adapters/net_http.rb +3 -2
  12. data/lib/webmock/http_lib_adapters/patron_adapter.rb +1 -1
  13. data/lib/webmock/request_body_diff.rb +1 -1
  14. data/lib/webmock/request_pattern.rb +2 -3
  15. data/lib/webmock/util/query_mapper.rb +4 -2
  16. data/lib/webmock/util/uri.rb +8 -8
  17. data/lib/webmock/version.rb +1 -1
  18. data/lib/webmock/webmock.rb +5 -0
  19. data/spec/acceptance/async_http_client/async_http_client_spec.rb +349 -0
  20. data/spec/acceptance/async_http_client/async_http_client_spec_helper.rb +73 -0
  21. data/spec/acceptance/curb/curb_spec.rb +11 -0
  22. data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +1 -1
  23. data/spec/acceptance/shared/callbacks.rb +2 -1
  24. data/spec/acceptance/shared/request_expectations.rb +7 -0
  25. data/spec/acceptance/shared/returning_declared_responses.rb +36 -15
  26. data/spec/acceptance/shared/stubbing_requests.rb +5 -0
  27. data/spec/support/webmock_server.rb +1 -0
  28. data/spec/unit/request_pattern_spec.rb +6 -1
  29. data/spec/unit/util/query_mapper_spec.rb +7 -0
  30. data/spec/unit/util/uri_spec.rb +74 -2
  31. data/spec/unit/webmock_spec.rb +8 -0
  32. data/webmock.gemspec +2 -3
  33. metadata +30 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a1f4b12d21d9712fdf49cc29d9494285c36926b29eda702e3821caab05ba7a97
4
- data.tar.gz: 24a7edb6ce921ef9735043588ee89ab31b895f9e99bccf3c655d20f645b3cf55
3
+ metadata.gz: 95babf82ad860e3ab49c323e66fcc785820dfecf100c03aa2fc126329e35c64a
4
+ data.tar.gz: 36d86569a52f5a999d9d2093a05a09fde833aaa669d94b94325ca11f03479027
5
5
  SHA512:
6
- metadata.gz: 724c7ae8d9ba016537b0e45968e9ae8d820458be36106a24eb7374ccc09cb3e06fb0df5968014443b4f94ba16349dad4643bf683cab17c4af1b32ae9c5b1112d
7
- data.tar.gz: 440171bbd565223139df3aec8581378497cfe359dc766c4b5e8dcf0b865a6c6adf759029d551b3ffac084d7b9683401baabd0b713930017563b7d79cb09320e8
6
+ metadata.gz: 34a48904414979c39edd9ee796172ea6a2018392b9a3a6e9ef28fc47b550e542f83c247382206e0d13fe51df8becd008f6b4e135976f7f08b3088fe13f680670
7
+ data.tar.gz: bb1a6e478680c68f109a0937f7b372a08e3f2a0385fa79386acae1ed5db35b679224376b62258472dcf55b66386166a8dcbf9c1580beb16938e439816f475873
@@ -3,19 +3,17 @@ before_install:
3
3
  - gem update bundler
4
4
  rvm:
5
5
  - 2.3.8
6
- - 2.4.5
7
- - 2.5.3
8
- - 2.6.0
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.5.0
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
@@ -1,5 +1,70 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.7.2
4
+
5
+ * Fixed handling of non UTF-8 encoded urls
6
+
7
+ Thanks to [Rafael França](https://github.com/rafaelfranca)
8
+
9
+ * Fixed "shadowing outer local variable" warning
10
+
11
+ Thanks to [y-yagi](https://github.com/y-yagi)
12
+
13
+ ## 3.7.1
14
+
15
+ * Fixed Async::HTTP::Client adapter code to not cause Ruby warning
16
+
17
+ Thanks to [y-yagi](https://github.com/y-yagi)
18
+
19
+ ## 3.7.0
20
+
21
+ * Support for Async::HTTP::Client
22
+
23
+ Thanks to [Andriy Yanko](https://github.com/ayanko)
24
+
25
+ ## 3.6.2
26
+
27
+ * Fixed Patron adapter to handle HTTP/2 status line.
28
+
29
+ Thanks to [Fábio D. Batista](https://github.com/fabiob)
30
+
31
+ ## 3.6.1
32
+
33
+ * Fixed issue with matching Addressable::Template without a period in the domain
34
+
35
+ Thanks to [Eike Send](https://github.com/eikes)
36
+
37
+ * Support for `write_timeout` in Net::HTTP
38
+
39
+ Thanks to [Claudio Poli](https://github.com/masterkain)
40
+
41
+ * Fixed issue with handling urls with ":80" or ":443" in the path.
42
+
43
+ Thanks to [Csaba Apagyi](https://github.com/thisismydesign) for reporting and to [Frederick Cheung](https://github.com/fcheung) for fixing the issue.
44
+
45
+ ## 3.6.0
46
+
47
+ * Compatibility with the latest version of hashdiff gem, with constant changed from HashDiff to Hashdiff
48
+
49
+ Thanks to [Jeff Felchner](https://github.com/jfelchner)
50
+
51
+ * Added a hint to the error message raised when `with` method is called without args or a block.
52
+
53
+ Thanks to [Adam Sokolnicki](https://github.com/asok)
54
+
55
+ * Resetting configured HTTP method in Curb adapter after each request
56
+
57
+ Thanks to [tiendo1011](https://github.com/tiendo1011)
58
+
59
+ * Added `WebMock.enable_net_connect!` as an alias for `WebMock.allow_net_connect!`
60
+ and `WebMock.disallow_net_connect!` as an alias for `WebMock.disable_net_connect!`
61
+
62
+ Thanks to [SoonKhen OwYong](https://github.com/owyongsk)
63
+
64
+ * Fixed handling of empty arrays as query params when using Faraday
65
+
66
+ Thanks to [Ryan Moret](https://github.com/rcmoret)
67
+
3
68
  ## 3.5.1
4
69
 
5
70
  * Disabling TracePoint defined in Net::BufferedIO in case of exception being raised.
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) [![Build Status](https://secure.travis-ci.org/bblimke/webmock.svg?branch=master)](http://travis-ci.org/bblimke/webmock) [![Dependency Status](https://gemnasium.com/bblimke/webmock.svg)](http://gemnasium.com/bblimke/webmock) [![Code Climate](https://codeclimate.com/github/bblimke/webmock/badges/gpa.svg)](https://codeclimate.com/github/bblimke/webmock) [![Mentioned in Awesome Ruby](https://awesome.re/mentioned-badge.svg)](https://github.com/markets/awesome-ruby) [![Inline docs](http://inch-ci.org/github/bblimke/webmock.svg?branch=master)](http://inch-ci.org/github/bblimke/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
  ---------------------------
@@ -873,6 +879,10 @@ end
873
879
 
874
880
  Please submit them here [http://github.com/bblimke/webmock/issues](http://github.com/bblimke/webmock/issues)
875
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
+
876
886
  ## Suggestions
877
887
 
878
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)
@@ -1086,6 +1096,20 @@ People who submitted patches and new features or suggested improvements. Many th
1086
1096
  * Geremia Taglialatela
1087
1097
  * Koichi Sasada
1088
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
+ * Rafael França
1112
+
1089
1113
 
1090
1114
  For a full list of contributors you can visit the
1091
1115
  [contributors](https://github.com/bblimke/webmock/contributors) page.
data/Rakefile CHANGED
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env rake
2
-
3
1
  require 'bundler'
4
2
  Bundler::GemHelper.install_tasks
5
3
 
@@ -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
@@ -107,7 +107,7 @@ if defined?(EventMachine::HttpClient)
107
107
  @uri ||= nil
108
108
  EM.next_tick {
109
109
  setup(make_raw_response(stubbed_webmock_response), @uri,
110
- stubbed_webmock_response.should_timeout ? "WebMock timeout error" : nil)
110
+ stubbed_webmock_response.should_timeout ? Errno::ETIMEDOUT : nil)
111
111
  }
112
112
  self
113
113
  elsif WebMock.net_connect_allowed?(request_signature.uri)
@@ -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).call
54
- real_request = false
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).call
58
- webmock_response = generate_webmock_response(manticore_response)
59
- real_request = true
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