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
@@ -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
@@ -411,6 +411,17 @@ unless RUBY_PLATFORM =~ /java/
411
411
  it_should_behave_like "Curb"
412
412
  include CurbSpecHelper::NamedHttp
413
413
 
414
+ it "should reset @webmock_method after each call" do
415
+ stub_request(:post, "www.example.com").with(body: "01234")
416
+ c = Curl::Easy.new
417
+ c.url = "http://www.example.com"
418
+ c.post_body = "01234"
419
+ c.http_post
420
+ expect {
421
+ c.perform
422
+ }.to raise_error(WebMock::NetConnectNotAllowedError, %r(Real HTTP connections are disabled. Unregistered request: GET http://www.example.com))
423
+ end
424
+
414
425
  it "should work with blank arguments for post" do
415
426
  stub_request(:post, "www.example.com").with(body: "01234")
416
427
  c = Curl::Easy.new
@@ -50,7 +50,7 @@ module EMHttpRequestSpecHelper
50
50
  end
51
51
 
52
52
  def client_timeout_exception_class
53
- "WebMock timeout error"
53
+ 'Errno::ETIMEDOUT'
54
54
  end
55
55
 
56
56
  def connection_refused_exception_class
@@ -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
@@ -172,6 +172,13 @@ shared_context "request expectations" do |*adapter_info|
172
172
  expect(a_request(:get, "www.example.com").with(query: hash_excluding(a: ['b', 'c']))).to have_been_made
173
173
  }.not_to raise_error
174
174
  end
175
+
176
+ it 'should satisfy expectation if the request was executed with an empty array in the query params' do
177
+ expect {
178
+ http_request(:get, "http://www.example.com/?a[]")
179
+ expect(a_request(:get, "www.example.com").with(query: hash_including(a: []))).to have_been_made
180
+ }.not_to raise_error
181
+ end
175
182
  end
176
183
 
177
184
  context "when using flat array notation" 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
@@ -68,6 +68,11 @@ shared_examples_for "stubbing requests" do |*adapter_info|
68
68
  stub_request(:get, 'www.example.com').with(query: hash_excluding(a: ['b', 'c'])).to_return(body: 'abc')
69
69
  expect(http_request(:get, 'http://www.example.com/?a[]=c&a[]=d&b=1').body).to eq('abc')
70
70
  end
71
+
72
+ it "should return stubbed response when stub expects an empty array" do
73
+ stub_request(:get, 'www.example.com').with(query: { a: [] }).to_return(body: 'abc')
74
+ expect(http_request(:get, 'http://www.example.com/?a[]').body).to eq('abc')
75
+ end
71
76
  end
72
77
 
73
78
  describe "based on method" do
@@ -36,6 +36,7 @@ class WebMockServer
36
36
  end
37
37
  end
38
38
  server.start do |socket|
39
+ socket.read(1)
39
40
  socket.puts <<-EOT.gsub(/^\s+\|/, '')
40
41
  |HTTP/1.1 200 OK\r
41
42
  |Date: Fri, 31 Dec 1999 23:59:59 GMT\r
@@ -58,7 +58,7 @@ describe WebMock::RequestPattern do
58
58
  end
59
59
 
60
60
  it "should raise an error if neither options or block is provided" do
61
- expect { @request_pattern.with() }.to raise_error('#with method invoked with no arguments. Either options hash or block must be specified.')
61
+ expect { @request_pattern.with() }.to raise_error('#with method invoked with no arguments. Either options hash or block must be specified. Created a block with do..end? Try creating it with curly braces {} instead.')
62
62
  end
63
63
  end
64
64
 
@@ -121,6 +121,11 @@ describe WebMock::RequestPattern do
121
121
  to match(WebMock::RequestSignature.new(:get, "www.example.com"))
122
122
  end
123
123
 
124
+ it "should match if uri Addressable::Template pattern matches request uri without TLD" do
125
+ expect(WebMock::RequestPattern.new(:get, Addressable::Template.new("localhost"))).
126
+ to match(WebMock::RequestSignature.new(:get, "localhost"))
127
+ end
128
+
124
129
  it "should match if Addressable::Template pattern that has ip address host matches request uri" do
125
130
  signature = WebMock::RequestSignature.new(:get, "127.0.0.1:3000/1234")
126
131
  uri = Addressable::Template.new("127.0.0.1:3000/{id}")
@@ -147,4 +147,11 @@ describe WebMock::Util::QueryMapper do
147
147
  expect(subject.values_to_query values).to eq query
148
148
  expect(subject.query_to_values query).to eq values
149
149
  end
150
+
151
+ it 'converts an empty array to ?' do
152
+ query = "one%5B%5D"
153
+ values = {"one" => []}
154
+ expect(subject.values_to_query values).to eq query
155
+ expect(subject.query_to_values query).to eq values
156
+ end
150
157
  end
@@ -1,6 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
-
4
3
  URIS_WITHOUT_PATH_OR_PARAMS =
5
4
  [
6
5
  "www.example.com",
@@ -65,7 +64,6 @@ URIS_WITH_DIFFERENT_PORT =
65
64
  "http://www.example.com:88/"
66
65
  ].sort
67
66
 
68
-
69
67
  URIS_FOR_HTTPS =
70
68
  [
71
69
  "https://www.example.com",
@@ -74,6 +72,49 @@ URIS_FOR_HTTPS =
74
72
  "https://www.example.com:443/"
75
73
  ].sort
76
74
 
75
+ URIS_FOR_LOCALHOST =
76
+ [
77
+ "localhost",
78
+ "localhost/",
79
+ "localhost:80",
80
+ "localhost:80/",
81
+ "http://localhost",
82
+ "http://localhost/",
83
+ "http://localhost:80",
84
+ "http://localhost:80/"
85
+ ].sort
86
+
87
+ URIS_WITH_SCHEME =
88
+ [
89
+ "http://www.example.com",
90
+ "http://www.example.com/",
91
+ "http://www.example.com:80",
92
+ "http://www.example.com:80/"
93
+ ].sort
94
+
95
+ URIS_WITH_COLON_IN_PATH =
96
+ [
97
+ [
98
+ "https://example.com/a/b:80",
99
+ "https://example.com:443/a/b:80",
100
+ ].sort,
101
+ [
102
+ "https://example.com:443/a/b:443",
103
+ "https://example.com/a/b:443",
104
+ ].sort,
105
+ [
106
+ "http://example.com/a/b:443",
107
+ "example.com/a/b:443",
108
+ "http://example.com:80/a/b:443",
109
+ "example.com:80/a/b:443",
110
+ ].sort,
111
+ [
112
+ "http://example.com/a/b:80",
113
+ "example.com/a/b:80",
114
+ "http://example.com:80/a/b:80",
115
+ "example.com:80/a/b:80",
116
+ ].sort
117
+ ]
77
118
 
78
119
  describe WebMock::Util::URI do
79
120
 
@@ -115,6 +156,37 @@ describe WebMock::Util::URI do
115
156
  end
116
157
  end
117
158
 
159
+ it "should find all variations of the same uri for all variations of host names uris without a period" do
160
+ URIS_FOR_LOCALHOST.each do |uri|
161
+ expect(WebMock::Util::URI.variations_of_uri_as_strings(uri).sort).to eq(URIS_FOR_LOCALHOST)
162
+ end
163
+ end
164
+
165
+ it "should find all variations of the same uri with scheme for all variations when only_with_scheme is true" do
166
+ URIS_WITHOUT_PATH_OR_PARAMS.each do |uri|
167
+ variations_of_uri_with_scheme = WebMock::Util::URI.variations_of_uri_as_strings(uri, only_with_scheme: true)
168
+ expect(variations_of_uri_with_scheme.sort).to eq(URIS_WITH_SCHEME)
169
+ end
170
+ end
171
+
172
+ it "should not replace :80 or :443 in path" do
173
+ URIS_WITH_COLON_IN_PATH.each do |uris|
174
+ uris.each do |uri|
175
+ expect(WebMock::Util::URI.variations_of_uri_as_strings(uri).sort).to eq(uris)
176
+ end
177
+ end
178
+ end
179
+
180
+ it "should find all variations of uris with https, basic auth, a non-standard port and a path" do
181
+ uri = "https://~%8A:pass@www.example.com:9000/foo"
182
+ variations = [
183
+ "https://~%8A:pass@www.example.com:9000/foo",
184
+ "https://~\x8A:pass@www.example.com:9000/foo".force_encoding(Encoding::ASCII_8BIT)
185
+ ]
186
+
187
+ expect(WebMock::Util::URI.variations_of_uri_as_strings(uri)).to eq(variations)
188
+ end
189
+
118
190
  end
119
191
 
120
192
  describe "normalized uri equality" do
@@ -8,4 +8,12 @@ describe "WebMock version" do
8
8
  it "should not require safe_yaml" do
9
9
  expect(defined?SafeYAML).to eq(nil)
10
10
  end
11
+
12
+ it "should alias enable_net_connect! to allow_net_connect!" do
13
+ expect(WebMock.method(:enable_net_connect!)).to eq(WebMock.method(:allow_net_connect!))
14
+ end
15
+
16
+ it "should alias disallow_net_connect! to disable_net_connect!" do
17
+ expect(WebMock.method(:disallow_net_connect!)).to eq(WebMock.method(:disable_net_connect!))
18
+ end
11
19
  end
@@ -13,13 +13,11 @@ Gem::Specification.new do |s|
13
13
  s.description = %q{WebMock allows stubbing HTTP requests and setting expectations on HTTP requests.}
14
14
  s.license = "MIT"
15
15
 
16
- s.rubyforge_project = 'webmock'
17
-
18
16
  s.required_ruby_version = '>= 2.0'
19
17
 
20
18
  s.add_dependency 'addressable', '>= 2.3.6'
21
19
  s.add_dependency 'crack', '>= 0.3.2'
22
- s.add_dependency 'hashdiff'
20
+ s.add_dependency 'hashdiff', ['>= 0.4.0', '< 2.0.0']
23
21
 
24
22
  unless RUBY_PLATFORM =~ /java/
25
23
  s.add_development_dependency 'patron', '>= 0.4.18'
@@ -35,6 +33,7 @@ Gem::Specification.new do |s|
35
33
  s.add_development_dependency 'em-http-request', '>= 1.0.2'
36
34
  s.add_development_dependency 'em-synchrony', '>= 1.0.0'
37
35
  s.add_development_dependency 'excon', '>= 0.27.5'
36
+ s.add_development_dependency 'async-http', '>= 0.48.0'
38
37
  s.add_development_dependency 'minitest', '>= 5.0.0'
39
38
  s.add_development_dependency 'test-unit', '>= 3.0.0'
40
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.5.1
4
+ version: 3.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bartosz Blimke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-27 00:00:00.000000000 Z
11
+ date: 2019-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -44,14 +44,20 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 0.4.0
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: 2.0.0
48
51
  type: :runtime
49
52
  prerelease: false
50
53
  version_requirements: !ruby/object:Gem::Requirement
51
54
  requirements:
52
55
  - - ">="
53
56
  - !ruby/object:Gem::Version
54
- version: '0'
57
+ version: 0.4.0
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: 2.0.0
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: patron
57
63
  requirement: !ruby/object:Gem::Requirement
@@ -192,6 +198,20 @@ dependencies:
192
198
  - - ">="
193
199
  - !ruby/object:Gem::Version
194
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
195
215
  - !ruby/object:Gem::Dependency
196
216
  name: minitest
197
217
  requirement: !ruby/object:Gem::Requirement
@@ -259,6 +279,7 @@ files:
259
279
  - lib/webmock/cucumber.rb
260
280
  - lib/webmock/deprecation.rb
261
281
  - lib/webmock/errors.rb
282
+ - lib/webmock/http_lib_adapters/async_http_client_adapter.rb
262
283
  - lib/webmock/http_lib_adapters/curb_adapter.rb
263
284
  - lib/webmock/http_lib_adapters/em_http_request_adapter.rb
264
285
  - lib/webmock/http_lib_adapters/excon_adapter.rb
@@ -312,6 +333,8 @@ files:
312
333
  - minitest/test_helper.rb
313
334
  - minitest/test_webmock.rb
314
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
315
338
  - spec/acceptance/curb/curb_spec.rb
316
339
  - spec/acceptance/curb/curb_spec_helper.rb
317
340
  - spec/acceptance/em_http_request/em_http_request_spec.rb
@@ -398,12 +421,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
398
421
  - !ruby/object:Gem::Version
399
422
  version: '0'
400
423
  requirements: []
401
- rubyforge_project: webmock
402
- rubygems_version: 2.7.6
424
+ rubygems_version: 3.0.3
403
425
  signing_key:
404
426
  specification_version: 4
405
427
  summary: Library for stubbing HTTP requests in Ruby.
406
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
407
431
  - spec/acceptance/curb/curb_spec.rb
408
432
  - spec/acceptance/curb/curb_spec_helper.rb
409
433
  - spec/acceptance/em_http_request/em_http_request_spec.rb