webmock 3.0.1 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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