webmock 3.0.1 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +7 -7
  3. data/CHANGELOG.md +60 -0
  4. data/README.md +18 -2
  5. data/lib/webmock/api.rb +8 -0
  6. data/lib/webmock/http_lib_adapters/curb_adapter.rb +2 -2
  7. data/lib/webmock/http_lib_adapters/excon_adapter.rb +2 -2
  8. data/lib/webmock/http_lib_adapters/http_rb/request.rb +7 -1
  9. data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +4 -0
  10. data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +1 -1
  11. data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +5 -3
  12. data/lib/webmock/http_lib_adapters/net_http.rb +2 -2
  13. data/lib/webmock/http_lib_adapters/patron_adapter.rb +2 -2
  14. data/lib/webmock/matchers/any_arg_matcher.rb +13 -0
  15. data/lib/webmock/matchers/hash_argument_matcher.rb +21 -0
  16. data/lib/webmock/matchers/hash_excluding_matcher.rb +15 -0
  17. data/lib/webmock/matchers/hash_including_matcher.rb +4 -23
  18. data/lib/webmock/rack_response.rb +1 -1
  19. data/lib/webmock/request_execution_verifier.rb +2 -3
  20. data/lib/webmock/request_pattern.rb +14 -3
  21. data/lib/webmock/request_registry.rb +1 -1
  22. data/lib/webmock/request_signature.rb +1 -1
  23. data/lib/webmock/request_signature_snippet.rb +4 -4
  24. data/lib/webmock/rspec.rb +8 -2
  25. data/lib/webmock/stub_request_snippet.rb +2 -2
  26. data/lib/webmock/util/headers.rb +2 -2
  27. data/lib/webmock/util/query_mapper.rb +3 -3
  28. data/lib/webmock/version.rb +1 -1
  29. data/lib/webmock.rb +3 -0
  30. data/minitest/webmock_spec.rb +2 -2
  31. data/spec/acceptance/http_rb/http_rb_spec.rb +9 -0
  32. data/spec/acceptance/http_rb/http_rb_spec_helper.rb +5 -2
  33. data/spec/acceptance/httpclient/httpclient_spec.rb +8 -1
  34. data/spec/acceptance/net_http/net_http_shared.rb +1 -1
  35. data/spec/acceptance/net_http/net_http_spec.rb +15 -1
  36. data/spec/acceptance/patron/patron_spec_helper.rb +1 -1
  37. data/spec/acceptance/shared/request_expectations.rb +7 -0
  38. data/spec/acceptance/shared/stubbing_requests.rb +5 -0
  39. data/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +1 -1
  40. data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +1 -1
  41. data/spec/unit/api_spec.rb +84 -3
  42. data/spec/unit/matchers/hash_excluding_matcher_spec.rb +61 -0
  43. data/spec/unit/request_execution_verifier_spec.rb +12 -12
  44. data/test/shared_test.rb +15 -2
  45. metadata +12 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b25e1f8ad8f3a8ffa79b1e54d0709069f9162b52
4
- data.tar.gz: 8169ef32ad67fecba074d929fb6d584410950617
3
+ metadata.gz: dcc2534597446961ba1489ab97892043fde75a6f
4
+ data.tar.gz: 1ef34b8d183d56935d2991b73cfa183d172f1df5
5
5
  SHA512:
6
- metadata.gz: 3daea98f13930398bd12722ff33b727c4c3b02ce41f2aeb3060d437d246ed5284c0737979bea0b7a46fa6dba6c24e90b1e4519d9b7f4e6d8d9e8d212869d9469
7
- data.tar.gz: 8f9fdee207513b9741f6245ed4b575120bd3232165edfa941a2f8113b11a2413f55945a5e5ce160cfb12da455545282b9e3f766903940fe7b878f49b5b59dbb9
6
+ metadata.gz: f5ed61bb690ad3b649b944d2fbfe5d6c636303befe3ef378a3096dc17aa087fbb19ea36f73623400ae97bf20a30decb864ff32ba3fd9c0e452ef4dbf5b75e060
7
+ data.tar.gz: e6d8db01788d4f7684cece257af0efa5ae975c2f194cf72c907883a212e35534a6e281d5ef8fa14cf6dc44d5e6b719464941592fa9cbbd86752124569e27774f
data/.travis.yml CHANGED
@@ -1,14 +1,14 @@
1
+ before_install:
2
+ - gem update bundler
3
+
1
4
  rvm:
2
- - 2.0.0
3
- - 2.1.0
4
- - 2.2.1
5
- - 2.2.3
6
- - 2.3.0
7
- - 2.4.0
5
+ - 2.2.8
6
+ - 2.3.5
7
+ - 2.4.2
8
8
  - rbx-2
9
9
  - ruby-head
10
10
  - jruby-9.0.5.0
11
- - jruby-9.1.5.0
11
+ - jruby-9.1.13.0
12
12
  - jruby-head
13
13
  matrix:
14
14
  allow_failures:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,65 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.2.0
4
+
5
+ * Automatically disable WebMock after Rspec suite
6
+
7
+ Thanks to [Michał Matyas](https://github.com/d4rky-pl)
8
+
9
+ * Fixed bug when handling redirection using Curb.
10
+
11
+ Thanks to [Olia Kremmyda](https://github.com/Olia-Kremmyda)
12
+
13
+
14
+ ## 3.1.1
15
+
16
+ * Warning message is displayed only once when adding query params to URIAddressablePattern.
17
+
18
+ ## 3.1.0
19
+
20
+ * http.rb 3.0.0 compatibility
21
+
22
+ Thanks to [Piotr Boniecki](https://github.com/Bonias)
23
+
24
+ * Typhoeus 1.3.0 support
25
+
26
+ Thanks to [NARUSE, Yui](https://github.com/nurse)
27
+
28
+ * Added support for matching partial query params using hash_excluding
29
+
30
+ stub_request(:get, "www.example.com").
31
+ with(query: hash_excluding({"a" => "b"}))
32
+
33
+ RestClient.get("http://www.example.com/?a=b") # ===> Failure
34
+ RestClient.get("http://www.example.com/?a=c") # ===> Success
35
+
36
+ Thanks to [Olexandr Hoshylyk](https://github.com/Warrior109)
37
+
38
+ * Added MRI 2.3+ frozen string literal compatibility
39
+
40
+ Thanks to [Pat Allan](https://github.com/pat)
41
+
42
+ * Ensured that HTTPClient adapter does not yield block on empty response body if a block is provided
43
+
44
+ Thanks to [NARUSE, Yui](https://github.com/nurse)
45
+
46
+ * Fixed issue with `to_timeout` incorrectly raising `HTTP::ConnectionError` instead of `HTTP::TimeoutError` when using http.rb
47
+
48
+ Thanks to [Rick Song](https://github.com/RickCSong)
49
+
50
+ * Fixed problem with `response.connection.close` method being undefined when using http.rb
51
+
52
+ Thanks to [Janko Marohnić](https://github.com/janko-m)
53
+
54
+ * Fixed problem with matching Net::HTTP request header values assigned as numbers.
55
+
56
+ Thanks to [Felipe Constantino de Oliveira](https://github.com/felipecdo) for reporting the issue.
57
+
58
+ * Fixed problem with Net::HTTP adapter converting empty response body to nil for non 204 responses.
59
+
60
+ Thanks to [Jeffrey Charles](https://github.com/jeffcharles) for reporting the issue.
61
+
62
+
3
63
  ## 3.0.1
4
64
 
5
65
  * Suppressed \`warning: \`&' interpreted as argument prefix\`
data/README.md CHANGED
@@ -32,8 +32,6 @@ Supported HTTP libraries
32
32
  Supported Ruby Interpreters
33
33
  ---------------------------
34
34
 
35
- * MRI 2.0
36
- * MRI 2.1
37
35
  * MRI 2.2
38
36
  * MRI 2.3
39
37
  * MRI 2.4
@@ -273,6 +271,16 @@ stub_request(:get, "www.example.com").
273
271
  RestClient.get("http://www.example.com/?a[]=b&a[]=c&x=1") # ===> Success
274
272
  ```
275
273
 
274
+ ### Matching partial query params using hash_excluding
275
+
276
+ ```ruby
277
+ stub_request(:get, "www.example.com").
278
+ with(query: hash_excluding({"a" => "b"}))
279
+
280
+ RestClient.get("http://www.example.com/?a=b") # ===> Failure
281
+ RestClient.get("http://www.example.com/?a=c") # ===> Success
282
+ ```
283
+
276
284
  ### Stubbing with custom response
277
285
 
278
286
  ```ruby
@@ -1035,6 +1043,14 @@ People who submitted patches and new features or suggested improvements. Many th
1035
1043
  * George Ulmer
1036
1044
  * Christof Koenig
1037
1045
  * Chung-Yi Chi
1046
+ * Olexandr Hoshylyk
1047
+ * Janko Marohnić
1048
+ * Pat Allan
1049
+ * Rick Song
1050
+ * NARUSE, Yui
1051
+ * Piotr Boniecki
1052
+ * Olia Kremmyda
1053
+ * Michał Matyas
1038
1054
 
1039
1055
  For a full list of contributors you can visit the
1040
1056
  [contributors](https://github.com/bblimke/webmock/contributors) page.
data/lib/webmock/api.rb CHANGED
@@ -54,6 +54,14 @@ module WebMock
54
54
  end
55
55
  end
56
56
 
57
+ def hash_excluding(*args)
58
+ if defined?(super)
59
+ super
60
+ else
61
+ WebMock::Matchers::HashExcludingMatcher.new(anythingize_lonely_keys(*args))
62
+ end
63
+ end
64
+
57
65
  def remove_request_stub(stub)
58
66
  WebMock::StubRegistry.instance.remove_request_stub(stub)
59
67
  end
@@ -153,7 +153,7 @@ if defined?(Curl)
153
153
  @body_str = webmock_response.body
154
154
  @response_code = webmock_response.status[0]
155
155
 
156
- @header_str = "HTTP/1.1 #{webmock_response.status[0]} #{webmock_response.status[1]}\r\n"
156
+ @header_str = "HTTP/1.1 #{webmock_response.status[0]} #{webmock_response.status[1]}\r\n".dup
157
157
 
158
158
  @on_debug.call(@header_str, 1) if defined?( @on_debug )
159
159
 
@@ -183,7 +183,7 @@ if defined?(Curl)
183
183
  self.url = location
184
184
 
185
185
  curb_or_webmock do
186
- send( "http_#{@webmock_method}_without_webmock" )
186
+ send( :http, {'method' => @webmock_method} )
187
187
  end
188
188
 
189
189
  self.url = first_url
@@ -92,7 +92,7 @@ if defined?(Excon)
92
92
  end
93
93
 
94
94
  def self.to_query(hash)
95
- string = ""
95
+ string = "".dup
96
96
  for key, values in hash
97
97
  if values.nil?
98
98
  string << key.to_s << '&'
@@ -152,7 +152,7 @@ if defined?(Excon)
152
152
  end
153
153
 
154
154
  Excon::Connection.class_eval do
155
- def self.new(args)
155
+ def self.new(args = {})
156
156
  args.delete(:__construction_args)
157
157
  super(args).tap do |instance|
158
158
  instance.data[:__construction_args] = args
@@ -1,9 +1,15 @@
1
1
  module HTTP
2
2
  class Request
3
3
  def webmock_signature
4
+ request_body = if defined?(HTTP::Request::Body)
5
+ ''.tap { |string| body.each { |part| string << part } }
6
+ else
7
+ body
8
+ end
9
+
4
10
  ::WebMock::RequestSignature.new(verb, uri.to_s, {
5
11
  headers: headers.to_h,
6
- body: body
12
+ body: request_body
7
13
  })
8
14
  end
9
15
  end
@@ -17,6 +17,10 @@ module HTTP
17
17
  @io.read size
18
18
  end
19
19
 
20
+ def close
21
+ @io.close
22
+ end
23
+
20
24
  def sequence_id
21
25
  -1
22
26
  end
@@ -43,7 +43,7 @@ module HTTP
43
43
 
44
44
  def raise_timeout_error
45
45
  raise Errno::ETIMEDOUT if HTTP::VERSION < "1.0.0"
46
- raise HTTP::ConnectionError, "connection error: #{Errno::ETIMEDOUT.new}"
46
+ raise HTTP::TimeoutError, "connection error: #{Errno::ETIMEDOUT.new}"
47
47
  end
48
48
 
49
49
  def perform
@@ -75,8 +75,10 @@ if defined?(::HTTPClient)
75
75
  elsif block
76
76
  body = ''
77
77
  do_get_block_without_webmock(req, proxy, conn) do |http_res, chunk|
78
- body += chunk
79
- block.call(http_res, chunk)
78
+ if chunk && chunk.bytesize > 0
79
+ body += chunk
80
+ block.call(http_res, chunk)
81
+ end
80
82
  end
81
83
  else
82
84
  do_get_block_without_webmock(req, proxy, conn)
@@ -117,7 +119,7 @@ if defined?(::HTTPClient)
117
119
  raise HTTPClient::TimeoutError if webmock_response.should_timeout
118
120
  webmock_response.raise_error_if_any
119
121
 
120
- block.call(response, body) if block
122
+ block.call(response, body) if block && body && body.bytesize > 0
121
123
 
122
124
  response
123
125
  end
@@ -154,7 +154,7 @@ module WebMock
154
154
  def build_net_http_response(webmock_response, &block)
155
155
  response = Net::HTTPResponse.send(:response_class, webmock_response.status[0].to_s).new("1.0", webmock_response.status[0].to_s, webmock_response.status[1])
156
156
  body = webmock_response.body
157
- body = nil if body.to_s == ''
157
+ body = nil if webmock_response.status[0].to_s == '204'
158
158
 
159
159
  response.instance_variable_set(:@body, body)
160
160
  webmock_response.headers.to_a.each do |name, values|
@@ -258,7 +258,7 @@ module Net #:nodoc: all
258
258
  class WebMockNetBufferedIO < BufferedIO
259
259
  def initialize(io, read_timeout: 60, continue_timeout: nil, debug_output: nil)
260
260
  @read_timeout = read_timeout
261
- @rbuf = ''
261
+ @rbuf = ''.dup
262
262
  @debug_output = debug_output
263
263
 
264
264
  @io = case io
@@ -106,11 +106,11 @@ if defined?(::Patron)
106
106
  header_data = ([status_line] + header_fields).join("\r\n")
107
107
 
108
108
  ::Patron::Response.new(
109
- "",
109
+ "".dup,
110
110
  webmock_response.status[0],
111
111
  0,
112
112
  header_data,
113
- webmock_response.body,
113
+ webmock_response.body.dup,
114
114
  default_response_charset
115
115
  )
116
116
  end
@@ -0,0 +1,13 @@
1
+ module WebMock
2
+ module Matchers
3
+ # this is a based on RSpec::Mocks::ArgumentMatchers::AnyArgMatcher
4
+ class AnyArgMatcher
5
+ def initialize(ignore)
6
+ end
7
+
8
+ def ==(other)
9
+ true
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ module WebMock
2
+ module Matchers
3
+ # Base class for Hash matchers
4
+ # https://github.com/rspec/rspec-mocks/blob/master/lib/rspec/mocks/argument_matchers.rb
5
+ class HashArgumentMatcher
6
+ def initialize(expected)
7
+ @expected = Hash[WebMock::Util::HashKeysStringifier.stringify_keys!(expected, deep: true).sort]
8
+ end
9
+
10
+ def ==(_actual, &block)
11
+ @expected.all?(&block)
12
+ rescue NoMethodError
13
+ false
14
+ end
15
+
16
+ def self.from_rspec_matcher(matcher)
17
+ new(matcher.instance_variable_get(:@expected))
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ module WebMock
2
+ module Matchers
3
+ # this is a based on RSpec::Mocks::ArgumentMatchers::HashExcludingMatcher
4
+ # https://github.com/rspec/rspec-mocks/blob/master/lib/rspec/mocks/argument_matchers.rb
5
+ class HashExcludingMatcher < HashArgumentMatcher
6
+ def ==(actual)
7
+ super { |key, value| !actual.key?(key) || value != actual[key] }
8
+ end
9
+
10
+ def inspect
11
+ "hash_excluding(#{@expected.inspect})"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,14 +1,10 @@
1
1
  module WebMock
2
2
  module Matchers
3
- #this is a based on RSpec::Mocks::ArgumentMatchers::HashIncludingMatcher
4
- #https://github.com/rspec/rspec-mocks/blob/master/lib/rspec/mocks/argument_matchers.rb
5
- class HashIncludingMatcher
6
- def initialize(expected)
7
- @expected = Hash[WebMock::Util::HashKeysStringifier.stringify_keys!(expected, deep: true).sort]
8
- end
9
-
3
+ # this is a based on RSpec::Mocks::ArgumentMatchers::HashIncludingMatcher
4
+ # https://github.com/rspec/rspec-mocks/blob/master/lib/rspec/mocks/argument_matchers.rb
5
+ class HashIncludingMatcher < HashArgumentMatcher
10
6
  def ==(actual)
11
- @expected.all? {|k,v| actual.has_key?(k) && v === actual[k]}
7
+ super { |key, value| actual.key?(key) && value === actual[key] }
12
8
  rescue NoMethodError
13
9
  false
14
10
  end
@@ -16,21 +12,6 @@ module WebMock
16
12
  def inspect
17
13
  "hash_including(#{@expected.inspect})"
18
14
  end
19
-
20
- def self.from_rspec_matcher(matcher)
21
- new(matcher.instance_variable_get(:@expected))
22
- end
23
- end
24
-
25
- #this is a based on RSpec::Mocks::ArgumentMatchers::AnyArgMatcher
26
- class AnyArgMatcher
27
- def initialize(ignore)
28
- end
29
-
30
- def ==(other)
31
- true
32
- end
33
15
  end
34
-
35
16
  end
36
17
  end
@@ -17,7 +17,7 @@ module WebMock
17
17
  end
18
18
 
19
19
  def body_from_rack_response(response)
20
- body = ""
20
+ body = "".dup
21
21
  response.each { |line| body << line }
22
22
  response.close if response.respond_to?(:close)
23
23
  return body
@@ -53,9 +53,8 @@ module WebMock
53
53
 
54
54
  def failure_message_phrase(is_negated=false)
55
55
  negation = is_negated ? "was not" : "was"
56
- text = "The request #{request_pattern} #{negation} expected to execute #{quantity_phrase(is_negated)}but it executed #{times(times_executed)}"
57
- text << self.class.executed_requests_message
58
- text
56
+ "The request #{request_pattern} #{negation} expected to execute #{quantity_phrase(is_negated)}but it executed #{times(times_executed)}" +
57
+ self.class.executed_requests_message
59
58
  end
60
59
 
61
60
  def quantity_phrase(is_negated=false)
@@ -4,6 +4,10 @@ module WebMock
4
4
  def rSpecHashIncludingMatcher?(matcher)
5
5
  matcher.class.name =~ /R?Spec::Mocks::ArgumentMatchers::HashIncludingMatcher/
6
6
  end
7
+
8
+ def rSpecHashExcludingMatcher?(matcher)
9
+ matcher.class.name =~ /R?Spec::Mocks::ArgumentMatchers::HashExcludingMatcher/
10
+ end
7
11
  end
8
12
 
9
13
  class RequestPattern
@@ -37,7 +41,7 @@ module WebMock
37
41
  end
38
42
 
39
43
  def to_s
40
- string = "#{@method_pattern.to_s.upcase}"
44
+ string = "#{@method_pattern.to_s.upcase}".dup
41
45
  string << " #{@uri_pattern.to_s}"
42
46
  string << " with body #{@body_pattern.to_s}" if @body_pattern
43
47
  string << " with headers #{@headers_pattern.to_s}" if @headers_pattern
@@ -115,10 +119,13 @@ module WebMock
115
119
  def add_query_params(query_params)
116
120
  @query_params = if query_params.is_a?(Hash)
117
121
  query_params
118
- elsif query_params.is_a?(WebMock::Matchers::HashIncludingMatcher)
122
+ elsif query_params.is_a?(WebMock::Matchers::HashIncludingMatcher) \
123
+ || query_params.is_a?(WebMock::Matchers::HashExcludingMatcher)
119
124
  query_params
120
125
  elsif rSpecHashIncludingMatcher?(query_params)
121
126
  WebMock::Matchers::HashIncludingMatcher.from_rspec_matcher(query_params)
127
+ elsif rSpecHashExcludingMatcher?(query_params)
128
+ WebMock::Matchers::HashExcludingMatcher.from_rspec_matcher(query_params)
122
129
  else
123
130
  WebMock::Util::QueryMapper.query_to_values(query_params, notation: Config.instance.query_values_notation)
124
131
  end
@@ -157,7 +164,11 @@ module WebMock
157
164
  end
158
165
 
159
166
  def add_query_params(query_params)
160
- warn "WebMock warning: ignoring query params in RFC 6570 template and checking them with WebMock"
167
+ @@add_query_params_warned ||= false
168
+ if not @@add_query_params_warned
169
+ @@add_query_params_warned = true
170
+ warn "WebMock warning: ignoring query params in RFC 6570 template and checking them with WebMock"
171
+ end
161
172
  super(query_params)
162
173
  end
163
174
 
@@ -23,7 +23,7 @@ module WebMock
23
23
  if requested_signatures.hash.empty?
24
24
  "No requests were made."
25
25
  else
26
- text = ""
26
+ text = "".dup
27
27
  self.requested_signatures.each do |request_signature, times_executed|
28
28
  text << "#{request_signature} was made #{times_executed} time#{times_executed == 1 ? '' : 's' }\n"
29
29
  end
@@ -12,7 +12,7 @@ module WebMock
12
12
  end
13
13
 
14
14
  def to_s
15
- string = "#{self.method.to_s.upcase}"
15
+ string = "#{self.method.to_s.upcase}".dup
16
16
  string << " #{WebMock::Util::URI.strip_default_port_from_uri_string(self.uri.to_s)}"
17
17
  string << " with body '#{body.to_s}'" if body && body.to_s != ''
18
18
  if headers && !headers.empty?
@@ -13,14 +13,14 @@ module WebMock
13
13
  def stubbing_instructions
14
14
  return unless WebMock.show_stubbing_instructions?
15
15
 
16
- text = "You can stub this request with the following snippet:\n\n"
17
- text << WebMock::StubRequestSnippet.new(request_stub).to_s
16
+ "You can stub this request with the following snippet:\n\n" +
17
+ WebMock::StubRequestSnippet.new(request_stub).to_s
18
18
  end
19
19
 
20
20
  def request_stubs
21
21
  return if WebMock::StubRegistry.instance.request_stubs.empty?
22
22
 
23
- text = "registered request stubs:\n"
23
+ text = "registered request stubs:\n".dup
24
24
  WebMock::StubRegistry.instance.request_stubs.each do |stub|
25
25
  text << "\n#{WebMock::StubRequestSnippet.new(stub).to_s(false)}"
26
26
  add_body_diff(stub, text) if WebMock.show_body_diff?
@@ -50,7 +50,7 @@ module WebMock
50
50
  end
51
51
 
52
52
  def pretty_print_to_string(string_to_print)
53
- StringIO.open("") do |stream|
53
+ StringIO.open("".dup) do |stream|
54
54
  PP.pp(string_to_print, stream)
55
55
  stream.rewind
56
56
  stream.read
data/lib/webmock/rspec.rb CHANGED
@@ -20,13 +20,19 @@ end
20
20
 
21
21
  require 'webmock/rspec/matchers'
22
22
 
23
- WebMock.enable!
24
-
25
23
  RSPEC_CONFIGURER.configure { |config|
26
24
 
27
25
  config.include WebMock::API
28
26
  config.include WebMock::Matchers
29
27
 
28
+ config.before(:suite) do
29
+ WebMock.enable!
30
+ end
31
+
32
+ config.after(:suite) do
33
+ WebMock.disable!
34
+ end
35
+
30
36
  config.after(:each) do
31
37
  WebMock.reset!
32
38
  end
@@ -10,10 +10,10 @@ module WebMock
10
10
 
11
11
  def to_s(with_response = true)
12
12
  request_pattern = @request_stub.request_pattern
13
- string = "stub_request(:#{request_pattern.method_pattern.to_s},"
13
+ string = "stub_request(:#{request_pattern.method_pattern.to_s},".dup
14
14
  string << " \"#{request_pattern.uri_pattern.to_s}\")"
15
15
 
16
- with = ""
16
+ with = "".dup
17
17
 
18
18
  if (request_pattern.body_pattern)
19
19
  with << "body: #{request_pattern.body_pattern.to_s}"
@@ -12,7 +12,7 @@ module WebMock
12
12
  [name.to_s.split(/_|-/).map { |segment| segment.capitalize }.join("-"),
13
13
  case value
14
14
  when Regexp then value
15
- when Array then (value.size == 1) ? value.first : value.map {|v| v.to_s}.sort
15
+ when Array then (value.size == 1) ? value.first.to_s : value.map {|v| v.to_s}.sort
16
16
  else value.to_s
17
17
  end
18
18
  ]
@@ -22,7 +22,7 @@ module WebMock
22
22
 
23
23
  def self.sorted_headers_string(headers)
24
24
  headers = WebMock::Util::Headers.normalize_headers(headers)
25
- str = '{'
25
+ str = '{'.dup
26
26
  str << headers.map do |k,v|
27
27
  v = case v
28
28
  when Regexp then v.inspect
@@ -204,7 +204,7 @@ module WebMock::Util
204
204
  end
205
205
  end
206
206
 
207
- buffer = ''
207
+ buffer = ''.dup
208
208
  new_query_values.each do |parent, value|
209
209
  encoded_parent = ::Addressable::URI.encode_component(
210
210
  parent.dup, ::Addressable::URI::CharacterClasses::UNRESERVED
@@ -251,14 +251,14 @@ module WebMock::Util
251
251
  ]
252
252
  end
253
253
  value.sort!
254
- buffer = ''
254
+ buffer = ''.dup
255
255
  value.each do |key, val|
256
256
  new_parent = options[:notation] != :flat_array ? "#{parent}[#{key}]" : parent
257
257
  buffer << "#{to_query(new_parent, val, options)}&"
258
258
  end
259
259
  buffer.chop
260
260
  when ::Array
261
- buffer = ''
261
+ buffer = ''.dup
262
262
  value.each_with_index do |val, i|
263
263
  new_parent = options[:notation] != :flat_array ? "#{parent}[#{i}]" : parent
264
264
  buffer << "#{to_query(new_parent, val, options)}&"
@@ -1,3 +1,3 @@
1
1
  module WebMock
2
- VERSION = '3.0.1' unless defined?(::WebMock::VERSION)
2
+ VERSION = '3.2.0' unless defined?(::WebMock::VERSION)
3
3
  end
data/lib/webmock.rb CHANGED
@@ -18,7 +18,10 @@ require 'webmock/util/json'
18
18
  require 'webmock/util/version_checker'
19
19
  require 'webmock/util/hash_validator'
20
20
 
21
+ require 'webmock/matchers/hash_argument_matcher'
22
+ require 'webmock/matchers/hash_excluding_matcher'
21
23
  require 'webmock/matchers/hash_including_matcher'
24
+ require 'webmock/matchers/any_arg_matcher'
22
25
 
23
26
  require 'webmock/request_pattern'
24
27
  require 'webmock/request_signature'
@@ -43,7 +43,7 @@ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
43
43
 
44
44
  it "should verify that expect request didn't occur" do
45
45
  expected_message = "The request GET http://www.example.com/ was expected to execute 1 time but it executed 0 times"
46
- expected_message << "\n\nThe following requests were made:\n\nNo requests were made.\n============================================================"
46
+ expected_message += "\n\nThe following requests were made:\n\nNo requests were made.\n============================================================"
47
47
  assert_fail(expected_message) do
48
48
  assert_requested(:get, "http://www.example.com")
49
49
  end
@@ -51,7 +51,7 @@ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
51
51
 
52
52
  it "should verify that expect stub didn't occur" do
53
53
  expected_message = "The request ANY http://www.example.com/ was expected to execute 1 time but it executed 0 times"
54
- expected_message << "\n\nThe following requests were made:\n\nNo requests were made.\n============================================================"
54
+ expected_message += "\n\nThe following requests were made:\n\nNo requests were made.\n============================================================"
55
55
  assert_fail(expected_message) do
56
56
  assert_requested(@stub_http)
57
57
  end
@@ -70,4 +70,13 @@ describe "HTTP.rb" do
70
70
  expect(response.uri.to_s).to eq "http://example.com/foo"
71
71
  end
72
72
  end
73
+
74
+ context "streamer" do
75
+ it "can be closed" do
76
+ stub_request :get, "example.com/foo"
77
+ response = HTTP.get "http://example.com/foo"
78
+
79
+ response.connection.close
80
+ end
81
+ end
73
82
  end
@@ -8,7 +8,10 @@ module HttpRbSpecHelper
8
8
  chain = chain.basic_auth(user: basic_auth[0], pass: basic_auth[1])
9
9
  end
10
10
 
11
- response = chain.request(method, normalize_uri(uri), options)
11
+ ssl_ctx = OpenSSL::SSL::SSLContext.new
12
+ ssl_ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
13
+
14
+ response = chain.request(method, normalize_uri(uri), options.merge(ssl_context: ssl_ctx))
12
15
 
13
16
  OpenStruct.new({
14
17
  body: response.body.to_s,
@@ -20,7 +23,7 @@ module HttpRbSpecHelper
20
23
 
21
24
  def client_timeout_exception_class
22
25
  return Errno::ETIMEDOUT if HTTP::VERSION < "1.0.0"
23
- HTTP::ConnectionError
26
+ HTTP::TimeoutError
24
27
  end
25
28
 
26
29
  def connection_refused_exception_class
@@ -31,6 +31,13 @@ describe "HTTPClient" do
31
31
  expect(response_body).to eq("abc")
32
32
  end
33
33
 
34
+ it "should not yield block on empty response if block provided" do
35
+ stub_request(:get, "www.example.com").to_return(body: "")
36
+ response_body = ""
37
+ http_request(:get, "http://www.example.com/"){ raise }
38
+ expect(response_body).to eq("")
39
+ end
40
+
34
41
  it "should match requests if headers are the same but in different order" do
35
42
  stub_request(:get, "www.example.com").with(headers: {"a" => ["b", "c"]} )
36
43
  expect(http_request(
@@ -48,7 +55,7 @@ describe "HTTPClient" do
48
55
 
49
56
  it "should work with get_content" do
50
57
  stub_request(:get, 'www.example.com').to_return(status: 200, body: 'test', headers: {})
51
- str = ''
58
+ str = ''.dup
52
59
  HTTPClient.get_content('www.example.com') do |content|
53
60
  str << content
54
61
  end
@@ -12,7 +12,7 @@ shared_examples_for "Net::HTTP" do
12
12
  end
13
13
 
14
14
  it "should handle requests with block passed to read_body", net_connect: true do
15
- body = ""
15
+ body = "".dup
16
16
  req = Net::HTTP::Get.new("/")
17
17
  Net::HTTP.start("localhost", port) do |http|
18
18
  http.request(req) do |res|
@@ -293,7 +293,7 @@ describe "Net:HTTP" do
293
293
  end
294
294
 
295
295
  it "should support the after_request callback on an request with block and read_body" do
296
- response_body = ''
296
+ response_body = ''.dup
297
297
  http_request(:get, "http://localhost:#{port}/") do |response|
298
298
  response.read_body { |fragment| response_body << fragment }
299
299
  end
@@ -314,4 +314,18 @@ describe "Net:HTTP" do
314
314
  expect(@callback_invocation_count).to eq(1)
315
315
  end
316
316
  end
317
+
318
+ it "should match http headers, even if their values have been set in a request as numbers" do
319
+ WebMock.disable_net_connect!
320
+
321
+ stub_request(:post, "www.example.com").with(headers: {"My-Header" => 99})
322
+
323
+ uri = URI.parse('http://www.example.com/')
324
+ req = Net::HTTP::Post.new(uri.path)
325
+ req['My-Header'] = 99
326
+
327
+ res = Net::HTTP.start(uri.host, uri.port) do |http|
328
+ http.request(req, '')
329
+ end
330
+ end
317
331
  end
@@ -16,7 +16,7 @@ module PatronSpecHelper
16
16
  sess.timeout = 30
17
17
  sess.max_redirects = 0
18
18
  uri = "#{uri.path}#{uri.query ? '?' : ''}#{uri.query}"
19
- uri.gsub!(' ','%20')
19
+ uri = uri.gsub(' ','%20')
20
20
  response = sess.request(method, uri, options[:headers] || {}, {
21
21
  data: options[:body]
22
22
  })
@@ -165,6 +165,13 @@ shared_context "request expectations" do |*adapter_info|
165
165
  expect(a_request(:get, "www.example.com").with(query: hash_including({"a" => ["b", "c"]}))).to have_been_made
166
166
  }.not_to raise_error
167
167
  end
168
+
169
+ it 'should satisfy expectation if the request was executed with excluding part of query params declared as a hash in a query option' do
170
+ expect {
171
+ http_request(:get, "http://www.example.com/?a[]=d&b[]=e&b=1")
172
+ expect(a_request(:get, "www.example.com").with(query: hash_excluding(a: ['b', 'c']))).to have_been_made
173
+ }.not_to raise_error
174
+ end
168
175
  end
169
176
 
170
177
  context "when using flat array notation" do
@@ -63,6 +63,11 @@ shared_examples_for "stubbing requests" do |*adapter_info|
63
63
  stub_request(:get, "www.example.com").with(query: hash_including({"a" => ["b", "c"]})).to_return(body: "abc")
64
64
  expect(http_request(:get, "http://www.example.com/?a[]=b&a[]=c&b=1").body).to eq("abc")
65
65
  end
66
+
67
+ it 'should return stubbed response when stub expects exclude part of query params' do
68
+ stub_request(:get, 'www.example.com').with(query: hash_excluding(a: ['b', 'c'])).to_return(body: 'abc')
69
+ expect(http_request(:get, 'http://www.example.com/?a[]=c&a[]=d&b=1').body).to eq('abc')
70
+ end
66
71
  end
67
72
 
68
73
  describe "based on method" do
@@ -127,7 +127,7 @@ unless RUBY_PLATFORM =~ /java/
127
127
  end
128
128
  hydra.queue @request
129
129
  hydra.run
130
- expect(test_headers).to include('X-Test' => '1')
130
+ expect(test_headers.to_h).to include('X-Test' => '1')
131
131
  end
132
132
  end
133
133
  end
@@ -6,7 +6,7 @@ module TyphoeusHydraSpecHelper
6
6
 
7
7
 
8
8
  def http_request(method, uri, options = {}, &block)
9
- uri.gsub!(" ", "%20") #typhoeus doesn't like spaces in the uri
9
+ uri = uri.gsub(" ", "%20") #typhoeus doesn't like spaces in the uri
10
10
  request_options = {
11
11
  method: method,
12
12
  body: options[:body],
@@ -2,9 +2,8 @@ require 'spec_helper'
2
2
 
3
3
  describe WebMock::API do
4
4
  describe '#hash_including' do
5
-
6
5
  subject { klass.new.hash_including(args) }
7
- let(:args) { {data: :one} }
6
+ let(:args) { { data: :one } }
8
7
 
9
8
  context 'when mixed into a class that does not define `hash_including`' do
10
9
  let(:klass) do
@@ -54,7 +53,7 @@ describe WebMock::API do
54
53
 
55
54
 
56
55
  context 'when mixed into a class with a parent that defines `hash_including`' do
57
- subject {klass.new.hash_including(*args)}
56
+ subject { klass.new.hash_including(*args) }
58
57
  let(:args) { %w(:foo, :bar, {:data => :one}) }
59
58
  let(:klass) do
60
59
  Class.new(
@@ -70,6 +69,88 @@ describe WebMock::API do
70
69
  expect(subject).to eq(args)
71
70
  end
72
71
  end
72
+ end
73
+
74
+ describe '#hash_excluding' do
75
+ subject { klass.new.hash_excluding(args) }
76
+ let(:args) { { data: :one } }
77
+
78
+ context 'when mixed into a class that does not define `hash_including`' do
79
+ let(:klass) do
80
+ Class.new do
81
+ include WebMock::API
82
+ end
83
+ end
84
+
85
+ it 'uses WebMock::Matchers::HashIncludingMatcher' do
86
+ expect(subject).to be_a(WebMock::Matchers::HashExcludingMatcher)
87
+ end
88
+
89
+ # by testing equality for HashIncludingMatcher (which stringifies the passed hash) we are
90
+ # testing HashIncludingMatcher.initialize behavior as well
91
+ context 'when args correspond to an hash' do
92
+ context 'creates "HashExcludingMatcher"' do
93
+ it 'equals hash with similar key but different value' do
94
+ expect(subject).to eq('data' => :two)
95
+ end
96
+
97
+ it 'equals hash with similar value but different key' do
98
+ expect(subject).to eq('data2' => :one)
99
+ end
100
+
101
+ it 'equals hash with defferent value and key' do
102
+ expect(subject).to eq('data2' => :two)
103
+ end
73
104
 
105
+ it 'not equals with similar value and key' do
106
+ expect(subject).not_to eq('data' => :one)
107
+ end
108
+ end
109
+ end
110
+
111
+ context 'when args are one or many keys' do
112
+ subject { klass.new.hash_excluding(:foo, :bar) }
113
+ let(:anything) { WebMock::Matchers::AnyArgMatcher.new(nil) }
114
+
115
+ it "creates 'HashExcludingMatcher' with keys anythingized" do
116
+ expect(subject).not_to eq('foo' => anything, 'bar' => anything )
117
+ end
118
+ end
119
+
120
+ context 'when args are both keys and key/value pairs' do
121
+ subject { klass.new.hash_excluding(:foo, :bar, data: :one) }
122
+ let(:anything) { WebMock::Matchers::AnyArgMatcher.new(nil) }
123
+
124
+ it 'creates "HashExcludingMatcher" with keys anythingized' do
125
+ expect(subject).not_to eq('foo' => anything, 'bar' => anything, 'data' => :one)
126
+ end
127
+ end
128
+
129
+ context 'when args are an empty hash' do
130
+ subject { klass.new.hash_excluding({}) }
131
+
132
+ it 'creates "HashExcludingMatcher" with an empty hash' do
133
+ expect(subject).to eq({})
134
+ end
135
+ end
136
+ end
137
+
138
+ context 'when mixed into a class with a parent that defines `hash_excluding`' do
139
+ subject { klass.new.hash_excluding(*args) }
140
+ let(:args) { %w(:foo, :bar, {:data => :one}) }
141
+ let(:klass) do
142
+ Class.new(
143
+ Class.new do
144
+ def hash_excluding(*args)
145
+ args
146
+ end
147
+ end
148
+ ) { include WebMock::API }
149
+ end
150
+
151
+ it 'uses super and passes the args untampered' do
152
+ expect(subject).to eq(args)
153
+ end
154
+ end
74
155
  end
75
156
  end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ module WebMock
4
+ module Matchers
5
+ describe HashExcludingMatcher do
6
+ it 'stringifies the given hash keys' do
7
+ expect(HashExcludingMatcher.new(a: 1, b: 2)).not_to eq('a' => 1, 'b' => 2)
8
+ end
9
+
10
+ it 'sorts elements in the hash' do
11
+ expect(HashExcludingMatcher.new(b: 2, a: 1)).not_to eq('a' => 1, 'b' => 2)
12
+ end
13
+
14
+ it 'describes itself properly' do
15
+ expect(HashExcludingMatcher.new(a: 1).inspect).to eq 'hash_excluding({"a"=>1})'
16
+ end
17
+
18
+ describe 'success' do
19
+ it 'match with hash with a missing key' do
20
+ expect(HashExcludingMatcher.new(a: 1)).to eq('b' => 2)
21
+ end
22
+
23
+ it 'match an empty hash with a given key' do
24
+ expect(HashExcludingMatcher.new(a: 1)).to eq({})
25
+ end
26
+
27
+ it 'match when values are nil but keys are different' do
28
+ expect(HashExcludingMatcher.new(a: nil)).to eq('b' => nil)
29
+ end
30
+
31
+ describe 'when matching an empty hash' do
32
+ it 'does not matches against any hash' do
33
+ expect(HashExcludingMatcher.new({})).to eq(a: 1, b: 2, c: 3)
34
+ end
35
+ end
36
+ end
37
+
38
+ describe 'failing' do
39
+ it 'does not match a hash with a one missing key when one pair is matching' do
40
+ expect(HashExcludingMatcher.new(a: 1, b: 2)).not_to eq('b' => 2)
41
+ end
42
+
43
+ it 'match a hash with an incorrect value' do
44
+ expect(HashExcludingMatcher.new(a: 1, b: 2)).not_to eq('a' => 1, 'b' => 3)
45
+ end
46
+
47
+ it 'does not matches the same hash' do
48
+ expect(HashExcludingMatcher.new('a' => 1, 'b' => 2)).not_to eq('a' => 1, 'b' => 2)
49
+ end
50
+
51
+ it 'does not matches a hash with extra stuff' do
52
+ expect(HashExcludingMatcher.new(a: 1)).not_to eq('a' => 1, 'b' => 2)
53
+ end
54
+
55
+ it 'does not match a non-hash' do
56
+ expect(HashExcludingMatcher.new(a: 1)).not_to eq 1
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -53,7 +53,7 @@ describe WebMock::RequestExecutionVerifier do
53
53
  @verifier.times_executed = 0
54
54
  @verifier.expected_times_executed = 2
55
55
  expected_text = "The request www.example.com was expected to execute 2 times but it executed 0 times"
56
- expected_text << @executed_requests_info
56
+ expected_text += @executed_requests_info
57
57
  expect(@verifier.failure_message).to eq(expected_text)
58
58
  end
59
59
 
@@ -61,7 +61,7 @@ describe WebMock::RequestExecutionVerifier do
61
61
  @verifier.times_executed = 1
62
62
  @verifier.expected_times_executed = 1
63
63
  expected_text = "The request www.example.com was expected to execute 1 time but it executed 1 time"
64
- expected_text << @executed_requests_info
64
+ expected_text += @executed_requests_info
65
65
  expect(@verifier.failure_message).to eq(expected_text)
66
66
  end
67
67
 
@@ -70,7 +70,7 @@ describe WebMock::RequestExecutionVerifier do
70
70
  @verifier.times_executed = 1
71
71
  @verifier.at_least_times_executed = 2
72
72
  expected_text = "The request www.example.com was expected to execute at least 2 times but it executed 1 time"
73
- expected_text << @executed_requests_info
73
+ expected_text += @executed_requests_info
74
74
  expect(@verifier.failure_message).to eq(expected_text)
75
75
  end
76
76
 
@@ -78,7 +78,7 @@ describe WebMock::RequestExecutionVerifier do
78
78
  @verifier.times_executed = 2
79
79
  @verifier.at_least_times_executed = 3
80
80
  expected_text = "The request www.example.com was expected to execute at least 3 times but it executed 2 times"
81
- expected_text << @executed_requests_info
81
+ expected_text += @executed_requests_info
82
82
  expect(@verifier.failure_message).to eq(expected_text)
83
83
  end
84
84
  end
@@ -88,7 +88,7 @@ describe WebMock::RequestExecutionVerifier do
88
88
  @verifier.times_executed = 3
89
89
  @verifier.at_most_times_executed = 2
90
90
  expected_text = "The request www.example.com was expected to execute at most 2 times but it executed 3 times"
91
- expected_text << @executed_requests_info
91
+ expected_text += @executed_requests_info
92
92
  expect(@verifier.failure_message).to eq(expected_text)
93
93
  end
94
94
 
@@ -96,7 +96,7 @@ describe WebMock::RequestExecutionVerifier do
96
96
  @verifier.times_executed = 2
97
97
  @verifier.at_most_times_executed = 1
98
98
  expected_text = "The request www.example.com was expected to execute at most 1 time but it executed 2 times"
99
- expected_text << @executed_requests_info
99
+ expected_text += @executed_requests_info
100
100
  expect(@verifier.failure_message).to eq(expected_text)
101
101
  end
102
102
  end
@@ -108,14 +108,14 @@ describe WebMock::RequestExecutionVerifier do
108
108
  @verifier.times_executed = 2
109
109
  @verifier.expected_times_executed = 2
110
110
  expected_text = "The request www.example.com was not expected to execute 2 times but it executed 2 times"
111
- expected_text << @executed_requests_info
111
+ expected_text += @executed_requests_info
112
112
  expect(@verifier.failure_message_when_negated).to eq(expected_text)
113
113
  end
114
114
 
115
115
  it "reports failure message when not expected request but it executed" do
116
116
  @verifier.times_executed = 1
117
117
  expected_text = "The request www.example.com was not expected to execute but it executed 1 time"
118
- expected_text << @executed_requests_info
118
+ expected_text += @executed_requests_info
119
119
  expect(@verifier.failure_message_when_negated).to eq(expected_text)
120
120
  end
121
121
 
@@ -124,7 +124,7 @@ describe WebMock::RequestExecutionVerifier do
124
124
  @verifier.times_executed = 3
125
125
  @verifier.at_least_times_executed = 2
126
126
  expected_text = "The request www.example.com was not expected to execute at least 2 times but it executed 3 times"
127
- expected_text << @executed_requests_info
127
+ expected_text += @executed_requests_info
128
128
  expect(@verifier.failure_message_when_negated).to eq(expected_text)
129
129
  end
130
130
 
@@ -132,7 +132,7 @@ describe WebMock::RequestExecutionVerifier do
132
132
  @verifier.times_executed = 2
133
133
  @verifier.at_least_times_executed = 2
134
134
  expected_text = "The request www.example.com was not expected to execute at least 2 times but it executed 2 times"
135
- expected_text << @executed_requests_info
135
+ expected_text += @executed_requests_info
136
136
  expect(@verifier.failure_message_when_negated).to eq(expected_text)
137
137
  end
138
138
  end
@@ -142,7 +142,7 @@ describe WebMock::RequestExecutionVerifier do
142
142
  @verifier.times_executed = 2
143
143
  @verifier.at_most_times_executed = 3
144
144
  expected_text = "The request www.example.com was not expected to execute at most 3 times but it executed 2 times"
145
- expected_text << @executed_requests_info
145
+ expected_text += @executed_requests_info
146
146
  expect(@verifier.failure_message_when_negated).to eq(expected_text)
147
147
  end
148
148
 
@@ -150,7 +150,7 @@ describe WebMock::RequestExecutionVerifier do
150
150
  @verifier.times_executed = 1
151
151
  @verifier.at_most_times_executed = 2
152
152
  expected_text = "The request www.example.com was not expected to execute at most 2 times but it executed 1 time"
153
- expected_text << @executed_requests_info
153
+ expected_text += @executed_requests_info
154
154
  expect(@verifier.failure_message_when_negated).to eq(expected_text)
155
155
  end
156
156
  end
data/test/shared_test.rb CHANGED
@@ -41,7 +41,7 @@ module SharedTest
41
41
 
42
42
  def test_verification_that_expected_request_didnt_occur
43
43
  expected_message = "The request GET http://www.example.com/ was expected to execute 1 time but it executed 0 times"
44
- expected_message << "\n\nThe following requests were made:\n\nNo requests were made.\n============================================================"
44
+ expected_message += "\n\nThe following requests were made:\n\nNo requests were made.\n============================================================"
45
45
  assert_fail(expected_message) do
46
46
  assert_requested(:get, "http://www.example.com")
47
47
  end
@@ -49,7 +49,7 @@ module SharedTest
49
49
 
50
50
  def test_verification_that_expected_stub_didnt_occur
51
51
  expected_message = "The request ANY http://www.example.com/ was expected to execute 1 time but it executed 0 times"
52
- expected_message << "\n\nThe following requests were made:\n\nNo requests were made.\n============================================================"
52
+ expected_message += "\n\nThe following requests were made:\n\nNo requests were made.\n============================================================"
53
53
  assert_fail(expected_message) do
54
54
  assert_requested(@stub_http)
55
55
  end
@@ -69,6 +69,19 @@ module SharedTest
69
69
  query: hash_including({"a" => ["b", "c"]}))
70
70
  end
71
71
 
72
+ def test_verification_that_expected_request_not_occured_with_query_params
73
+ stub_request(:any, 'http://www.example.com').with(query: hash_including(a: ['b', 'c']))
74
+ stub_request(:any, 'http://www.example.com').with(query: hash_excluding(a: ['b', 'c']))
75
+ http_request(:get, 'http://www.example.com/?a[]=b&a[]=c&x=1')
76
+ assert_not_requested(:get, 'http://www.example.com', query: hash_excluding('a' => ['b', 'c']))
77
+ end
78
+
79
+ def test_verification_that_expected_request_occured_with_excluding_query_params
80
+ stub_request(:any, 'http://www.example.com').with(query: hash_excluding('a' => ['b', 'c']))
81
+ http_request(:get, 'http://www.example.com/?a[]=x&a[]=y&x=1')
82
+ assert_requested(:get, 'http://www.example.com', query: hash_excluding('a' => ['b', 'c']))
83
+ end
84
+
72
85
  def test_verification_that_non_expected_request_didnt_occur
73
86
  expected_message = %r(The request GET http://www.example.com/ was not expected to execute but it executed 1 time\n\nThe following requests were made:\n\nGET http://www.example.com/ with headers .+ was made 1 time\n\n============================================================)
74
87
  assert_fail(expected_message) do
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.0.1
4
+ version: 3.2.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: 2017-04-12 00:00:00.000000000 Z
11
+ date: 2018-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -112,16 +112,16 @@ dependencies:
112
112
  name: rack
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - '='
115
+ - - ">"
116
116
  - !ruby/object:Gem::Version
117
- version: 1.6.0
117
+ version: '1.6'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - '='
122
+ - - ">"
123
123
  - !ruby/object:Gem::Version
124
- version: 1.6.0
124
+ version: '1.6'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rspec
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -276,6 +276,9 @@ files:
276
276
  - lib/webmock/http_lib_adapters/net_http_response.rb
277
277
  - lib/webmock/http_lib_adapters/patron_adapter.rb
278
278
  - lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb
279
+ - lib/webmock/matchers/any_arg_matcher.rb
280
+ - lib/webmock/matchers/hash_argument_matcher.rb
281
+ - lib/webmock/matchers/hash_excluding_matcher.rb
279
282
  - lib/webmock/matchers/hash_including_matcher.rb
280
283
  - lib/webmock/minitest.rb
281
284
  - lib/webmock/rack_response.rb
@@ -349,6 +352,7 @@ files:
349
352
  - spec/unit/errors_spec.rb
350
353
  - spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb
351
354
  - spec/unit/http_lib_adapters/http_lib_adapter_spec.rb
355
+ - spec/unit/matchers/hash_excluding_matcher_spec.rb
352
356
  - spec/unit/matchers/hash_including_matcher_spec.rb
353
357
  - spec/unit/rack_response_spec.rb
354
358
  - spec/unit/request_body_diff_spec.rb
@@ -394,7 +398,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
394
398
  version: '0'
395
399
  requirements: []
396
400
  rubyforge_project: webmock
397
- rubygems_version: 2.2.2
401
+ rubygems_version: 2.6.13
398
402
  signing_key:
399
403
  specification_version: 4
400
404
  summary: Library for stubbing HTTP requests in Ruby.
@@ -440,6 +444,7 @@ test_files:
440
444
  - spec/unit/errors_spec.rb
441
445
  - spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb
442
446
  - spec/unit/http_lib_adapters/http_lib_adapter_spec.rb
447
+ - spec/unit/matchers/hash_excluding_matcher_spec.rb
443
448
  - spec/unit/matchers/hash_including_matcher_spec.rb
444
449
  - spec/unit/rack_response_spec.rb
445
450
  - spec/unit/request_body_diff_spec.rb