webmock 1.13.0 → 1.14.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.
@@ -1,5 +1,35 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.14.0
4
+
5
+ * Handling non UTF-8 characters in query params.
6
+
7
+ Thanks to [Florian Dütsch](https://github.com/der-flo) for reporting the issue.
8
+
9
+ * Added support for `request_block` param in Excon
10
+
11
+ Thanks to [Dmitry Gutov](https://github.com/dgutov) for reporting the issue.
12
+
13
+ * Fixed compatibility with latest Curb
14
+
15
+ Thanks to [Ian Lesperance](https://github.com/elliterate) and [Matthew Horan](https://github.com/mhoran)
16
+
17
+ * Triggering errbacks assynchronously in em-http-request adapter.
18
+
19
+ Thanks to [Ian Lesperance](https://github.com/elliterate) and [Matthew Horan](https://github.com/mhoran)
20
+
21
+ * Handling query params with a hashes nested inside arrays.
22
+
23
+ Thanks to [Ian Asaff](https://github.com/montague)
24
+
25
+ * Changed NetConnectNotAllowedError to inherit from Exception to allow it to bubble up into a test suite.
26
+
27
+ Thanks to [Daniel van Hoesel](https://github.com/s0meone)
28
+
29
+ * HTTPClient adapter is thread safe.
30
+
31
+ Thanks to [Tom Beauvais](https://github.com/tbeauvais)
32
+
3
33
  ## 1.13.0
4
34
 
5
35
  * Net::HTTP::Persistent compatibility.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- WebMock [![Build Status](https://secure.travis-ci.org/bblimke/webmock.png?branch=master)](http://travis-ci.org/bblimke/webmock) [![Dependency Status](https://gemnasium.com/bblimke/webmock.png)](http://gemnasium.com/bblimke/webmock) [![Stories in Ready](http://badge.waffle.io/bblimke/webmock.png)](http://waffle.io/bblimke/webmock)
1
+ WebMock [![Build Status](https://secure.travis-ci.org/bblimke/webmock.png?branch=master)](http://travis-ci.org/bblimke/webmock) [![Dependency Status](https://gemnasium.com/bblimke/webmock.png)](http://gemnasium.com/bblimke/webmock)
2
2
  =======
3
3
 
4
4
  Library for stubbing and setting expectations on HTTP requests in Ruby.
@@ -258,7 +258,10 @@ Net::HTTP.start("www.example.com") {|http| http.request(req)}.message # ===>
258
258
 
259
259
  ### Replaying raw responses recorded with `curl -is`
260
260
 
261
- `curl -is www.example.com > /tmp/example_curl_-is_output.txt`
261
+ ```
262
+ curl -is www.example.com > /tmp/example_curl_-is_output.txt
263
+ ```
264
+
262
265
  ```ruby
263
266
  raw_response_file = File.new("/tmp/example_curl_-is_output.txt")
264
267
  ```
@@ -850,6 +853,13 @@ People who submitted patches and new features or suggested improvements. Many th
850
853
  * Leif Bladt
851
854
  * Alex Tomlins
852
855
  * Mitsutaka Mimura
856
+ * Tomy Kaira
857
+ * Daniel van Hoesel
858
+ * Ian Asaff
859
+ * Ian Lesperance
860
+ * Matthew Horan
861
+ * Dmitry Gutov
862
+ * Florian Dütsch
853
863
 
854
864
  For a full list of contributors you can visit the
855
865
  [contributors](https://github.com/bblimke/webmock/contributors) page.
@@ -1,6 +1,6 @@
1
1
  module WebMock
2
2
 
3
- class NetConnectNotAllowedError < StandardError
3
+ class NetConnectNotAllowedError < Exception
4
4
  def initialize(request_signature)
5
5
  text = "Real HTTP connections are disabled. Unregistered request: #{request_signature}"
6
6
  text << "\n\n"
@@ -94,7 +94,6 @@ if defined?(EventMachine::HttpClient)
94
94
  WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
95
95
 
96
96
  if stubbed_webmock_response
97
- on_error("WebMock timeout error") if stubbed_webmock_response.should_timeout
98
97
  WebMock::CallbackRegistry.invoke_callbacks({:lib => :em_http_request}, request_signature, stubbed_webmock_response)
99
98
  EM.next_tick {
100
99
  setup(make_raw_response(stubbed_webmock_response), @uri,
@@ -13,7 +13,7 @@ if defined?(Excon)
13
13
  class ExconAdapter < HttpLibAdapter
14
14
  PARAMS_TO_DELETE = [:expects, :idempotent,
15
15
  :instrumentor_name, :instrumentor,
16
- :response_block, :request_block,
16
+ :response_block,
17
17
  :__construction_args, :stack,
18
18
  :connection, :response]
19
19
 
@@ -37,6 +37,7 @@ module WebMock::Util
37
37
  # "?one=two&one=three").query_values(:notation => :flat_array)
38
38
  # #=> [['one', 'two'], ['one', 'three']]
39
39
  def self.query_to_values(query, options={})
40
+ query.force_encoding('utf-8') if query.respond_to?(:force_encoding)
40
41
  defaults = {:notation => :subscript}
41
42
  options = defaults.merge(options)
42
43
  if ![:flat, :dot, :subscript, :flat_array].include?(options[:notation])
@@ -65,6 +66,7 @@ module WebMock::Util
65
66
  end).compact.inject(empty_accumulator.dup) do |accumulator, (key, value)|
66
67
  value = true if value.nil?
67
68
  key = Addressable::URI.unencode_component(key)
69
+ key = key.dup.force_encoding(Encoding::ASCII_8BIT) if key.respond_to?(:force_encoding)
68
70
  if value != true
69
71
  value = Addressable::URI.unencode_component(value.gsub(/\+/, " "))
70
72
  end
@@ -90,6 +92,9 @@ module WebMock::Util
90
92
  current_hash = current_hash[subkey]
91
93
  end
92
94
  if array_value
95
+ if current_hash[subkeys.last] && !current_hash[subkeys.last].is_a?(Array)
96
+ current_hash[subkeys.last] = [current_hash[subkeys.last]]
97
+ end
93
98
  current_hash[subkeys.last] = [] unless current_hash[subkeys.last]
94
99
  current_hash[subkeys.last] << value
95
100
  else
@@ -78,7 +78,10 @@ module WebMock
78
78
  end
79
79
 
80
80
  def self.uris_with_inferred_port_and_without(uris)
81
- uris.map { |uri| [ uri, uri.gsub(%r{(:80)|(:443)}, "").freeze ] }.flatten
81
+ uris.map { |uri|
82
+ uri = uri.dup.force_encoding(Encoding::ASCII_8BIT) if uri.respond_to?(:force_encoding)
83
+ [ uri, uri.gsub(%r{(:80)|(:443)}, "").freeze ]
84
+ }.flatten
82
85
  end
83
86
 
84
87
  def self.uris_encoded_and_unencoded(uris)
@@ -88,11 +91,17 @@ module WebMock
88
91
  end
89
92
 
90
93
  def self.uris_with_scheme_and_without(uris)
91
- uris.map { |uri| [ uri, uri.gsub(%r{^https?://},"").freeze ] }.flatten
94
+ uris.map { |uri|
95
+ uri = uri.dup.force_encoding(Encoding::ASCII_8BIT) if uri.respond_to?(:force_encoding)
96
+ [ uri, uri.gsub(%r{^https?://},"").freeze ]
97
+ }.flatten
92
98
  end
93
99
 
94
100
  def self.uris_with_trailing_slash_and_without(uris)
95
- uris = uris.map { |uri| [ uri, uri.omit(:path).freeze ] }.flatten
101
+ uris = uris.map { |uri|
102
+ uri = uri.dup.force_encoding(Encoding::ASCII_8BIT) if uri.respond_to?(:force_encoding)
103
+ [ uri, uri.omit(:path).freeze ]
104
+ }.flatten
96
105
  end
97
106
 
98
107
  end
@@ -1,3 +1,3 @@
1
1
  module WebMock
2
- VERSION = '1.13.0' unless defined?(::WebMock::VERSION)
2
+ VERSION = '1.14.0' unless defined?(::WebMock::VERSION)
3
3
  end
@@ -66,7 +66,7 @@ module CurbSpecHelper
66
66
  curl.put_data = body
67
67
  end
68
68
 
69
- curl.http(method)
69
+ curl.http(method.to_s.upcase)
70
70
  curl
71
71
  end
72
72
  end
@@ -127,6 +127,23 @@ unless RUBY_PLATFORM =~ /java/
127
127
  end
128
128
  end
129
129
 
130
+ it 'should trigger error callbacks asynchronously' do
131
+ stub_request(:get, 'www.example.com').to_timeout
132
+ called = false
133
+
134
+ EM.run do
135
+ conn = EventMachine::HttpRequest.new('http://www.example.com/')
136
+ http = conn.get
137
+ http.errback do
138
+ called = true
139
+ EM.stop
140
+ end
141
+ called.should == false
142
+ end
143
+
144
+ called.should == true
145
+ end
146
+
130
147
  # not pretty, but it works
131
148
  if defined?(EventMachine::Synchrony)
132
149
  describe "with synchrony" do
@@ -83,7 +83,7 @@ shared_context "allowing and disabling net connect" do |*adapter_info|
83
83
  let(:host_with_port){ WebMockServer.instance.host_with_port }
84
84
 
85
85
  before(:each) do
86
- WebMock.disable_net_connect!(:allow => ["www.example.org", host_with_port])
86
+ WebMock.disable_net_connect!(:allow => ["www.example.org", "httpstat.us", host_with_port])
87
87
  end
88
88
 
89
89
  context "when the host is not allowed" do
@@ -120,7 +120,7 @@ shared_context "allowing and disabling net connect" do |*adapter_info|
120
120
  end
121
121
 
122
122
  it "should make a real request to allowed host", :net_connect => true do
123
- http_request(:get, "http://www.example.org/").status.should == "302"
123
+ http_request(:get, "http://httpstat.us/200").status.should == "200"
124
124
  end
125
125
  end
126
126
 
@@ -101,20 +101,20 @@ shared_context "callbacks" do |*adapter_info|
101
101
  WebMock.after_request(:except => [:other_lib]) do |_, response|
102
102
  @response = response
103
103
  end
104
- http_request(:get, "http://www.example.com/")
104
+ http_request(:get, "http://httpstat.us/200")
105
105
  end
106
106
 
107
107
  it "should pass real response to callback with status and message" do
108
- @response.status[0].should == 302
109
- @response.status[1].should == "Found" unless adapter_info.include?(:no_status_message)
108
+ @response.status[0].should == 200
109
+ @response.status[1].should == "OK" unless adapter_info.include?(:no_status_message)
110
110
  end
111
111
 
112
112
  it "should pass real response to callback with headers" do
113
- @response.headers["Content-Length"].should == "0"
113
+ @response.headers["Content-Length"].should == "6"
114
114
  end
115
115
 
116
116
  it "should pass response to callback with body" do
117
- @response.body.size.should == 0
117
+ @response.body.size.should == 6
118
118
  end
119
119
  end
120
120
  end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  shared_examples_for "stubbing requests" do |*adapter_info|
2
4
  describe "when requests are stubbed" do
3
5
  describe "based on uri" do
@@ -16,6 +18,13 @@ shared_examples_for "stubbing requests" do |*adapter_info|
16
18
  http_request(:get, "http://www.example.com/hello+/?#{NOT_ESCAPED_PARAMS}").body.should == "abc"
17
19
  end
18
20
 
21
+ it "should return stubbed response for url with non utf query params", "ruby>1.9" => true do
22
+ param = 'aäoöuü'.encode('iso-8859-1')
23
+ param = CGI.escape(param)
24
+ stub_request(:get, "www.example.com/?#{param}").to_return(:body => "abc")
25
+ http_request(:get, "http://www.example.com/?#{param}").body.should == "abc"
26
+ end
27
+
19
28
  it "should return stubbed response even if stub uri is declared as regexp and request params are escaped" do
20
29
  stub_request(:get, /.*x=ab c.*/).to_return(:body => "abc")
21
30
  http_request(:get, "http://www.example.com/hello/?#{ESCAPED_PARAMS}").body.should == "abc"
@@ -28,6 +28,10 @@ RSpec.configure do |config|
28
28
  config.filter_run_excluding :net_connect => true
29
29
  end
30
30
 
31
+ if RUBY_VERSION <= "1.8.7"
32
+ config.filter_run_excluding "ruby>1.9" => true
33
+ end
34
+
31
35
  config.filter_run_excluding :without_webmock => true
32
36
 
33
37
  config.before(:suite) do
@@ -16,7 +16,7 @@ module NetworkConnection
16
16
 
17
17
  def self.is_network_available?
18
18
  begin
19
- self.connect_to("192.0.32.10", 80, 5)
19
+ self.connect_to("173.194.113.176", 80, 5)
20
20
  true
21
21
  rescue
22
22
  false
@@ -4,11 +4,11 @@ describe "errors" do
4
4
  describe WebMock::NetConnectNotAllowedError do
5
5
  describe "message" do
6
6
  it "should have message with request signature and snippet" do
7
- request_signature = mock(:to_s => "aaa")
8
- request_stub = mock
9
- WebMock::RequestStub.stub!(:from_request_signature).and_return(request_stub)
10
- WebMock::StubRequestSnippet.stub!(:new).
11
- with(request_stub).and_return(mock(:to_s => "bbb"))
7
+ request_signature = double(:to_s => "aaa")
8
+ request_stub = double
9
+ WebMock::RequestStub.stub(:from_request_signature).and_return(request_stub)
10
+ WebMock::StubRequestSnippet.stub(:new).
11
+ with(request_stub).and_return(double(:to_s => "bbb"))
12
12
  expected = "Real HTTP connections are disabled. Unregistered request: aaa" +
13
13
  "\n\nYou can stub this request with the following snippet:\n\n" +
14
14
  "bbb\n\n============================================================"
@@ -16,16 +16,34 @@ describe "errors" do
16
16
  end
17
17
 
18
18
  it "should have message with registered stubs if available" do
19
+ request_signature = double(:to_s => "aaa")
20
+ request_stub = double
21
+ WebMock::StubRegistry.instance.stub(:request_stubs).and_return([request_stub])
22
+ WebMock::RequestStub.stub(:from_request_signature).and_return(request_stub)
23
+ WebMock::StubRequestSnippet.stub(:new).
24
+ with(request_stub).and_return(double(:to_s => "bbb"))
25
+ expected = "Real HTTP connections are disabled. Unregistered request: aaa" +
26
+ "\n\nYou can stub this request with the following snippet:\n\n" +
27
+ "bbb\n\nregistered request stubs:\n\nbbb\n\n============================================================"
28
+ WebMock::NetConnectNotAllowedError.new(request_signature).message.should == expected
29
+ end
30
+
31
+ it "should not be caught by a rescue block without arguments" do
19
32
  request_signature = mock(:to_s => "aaa")
20
33
  request_stub = mock
21
- WebMock::StubRegistry.instance.stub!(:request_stubs).and_return([request_stub])
22
34
  WebMock::RequestStub.stub!(:from_request_signature).and_return(request_stub)
23
35
  WebMock::StubRequestSnippet.stub!(:new).
24
36
  with(request_stub).and_return(mock(:to_s => "bbb"))
25
- expected = "Real HTTP connections are disabled. Unregistered request: aaa" +
26
- "\n\nYou can stub this request with the following snippet:\n\n" +
27
- "bbb\n\nregistered request stubs:\n\nbbb\n\n============================================================"
28
- WebMock::NetConnectNotAllowedError.new(request_signature).message.should == expected
37
+
38
+ exception = WebMock::NetConnectNotAllowedError.new(request_signature)
39
+
40
+ expect do
41
+ begin
42
+ raise exception
43
+ rescue
44
+ raise "exception should not be caught"
45
+ end
46
+ end.to raise_exception exception
29
47
  end
30
48
  end
31
49
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe WebMock::RequestExecutionVerifier do
4
4
  before(:each) do
5
5
  @verifier = WebMock::RequestExecutionVerifier.new
6
- @request_pattern = mock(WebMock::RequestPattern, :to_s => "www.example.com")
6
+ @request_pattern = double(WebMock::RequestPattern, :to_s => "www.example.com")
7
7
  @verifier.request_pattern = @request_pattern
8
8
  WebMock::RequestRegistry.instance.stub(:to_s).and_return("executed requests")
9
9
  @executed_requests_info = "\n\nThe following requests were made:\n\nexecuted requests\n" + "="*60
@@ -6,14 +6,14 @@ describe WebMock::ResponseFactory do
6
6
 
7
7
  it "should create response with options passed as arguments" do
8
8
  options = {:body => "abc", :headers => {:a => :b}}
9
- WebMock::Response.should_receive(:new).with(options).and_return(@response = mock(WebMock::Response))
9
+ WebMock::Response.should_receive(:new).with(options).and_return(@response = double(WebMock::Response))
10
10
  WebMock::ResponseFactory.response_for(options).should == @response
11
11
  end
12
12
 
13
13
 
14
14
  it "should create dynamic response for argument responding to call" do
15
- callable = mock(:call => {:body => "abc"})
16
- WebMock::DynamicResponse.should_receive(:new).with(callable).and_return(@response = mock(WebMock::Response))
15
+ callable = double(:call => {:body => "abc"})
16
+ WebMock::DynamicResponse.should_receive(:new).with(callable).and_return(@response = double(WebMock::Response))
17
17
  WebMock::ResponseFactory.response_for(callable).should == @response
18
18
  end
19
19
 
@@ -184,6 +184,19 @@ describe WebMock::Util::URI do
184
184
  uri = WebMock::Util::URI.normalize_uri(uri_string)
185
185
  WebMock::Util::QueryMapper.query_to_values(uri.query).should == {"one"=>{"two"=>{"three" => ["four", "five"]}}}
186
186
  end
187
+
188
+ it "should successfully handle mixed array and hash parameters" do
189
+ # derived from an elasticsearch query:
190
+ # load => {
191
+ # :include => [
192
+ # { :staff => :email },
193
+ # :business_name
194
+ # ]
195
+ # }
196
+ uri_string = "http://www.example.com:80/path?load[include][][staff]=email&load[include][]=business_name"
197
+ uri = WebMock::Util::URI.normalize_uri(uri_string)
198
+ WebMock::Util::QueryMapper.query_to_values(uri.query).should == {"load"=>{"include"=>[{"staff"=>"email"},"business_name"]}}
199
+ end
187
200
  end
188
201
 
189
202
  describe "stripping default port" do
@@ -10,13 +10,13 @@ module SharedTest
10
10
  end
11
11
 
12
12
  def test_assert_requested_with_stub_and_block_raises_error
13
- assert_raise ArgumentError do
13
+ assert_raises ArgumentError do
14
14
  assert_requested(@stub_http) {}
15
15
  end
16
16
  end
17
17
 
18
18
  def test_assert_not_requested_with_stub_and_block_raises_error
19
- assert_raise ArgumentError do
19
+ assert_raises ArgumentError do
20
20
  assert_not_requested(@stub_http) {}
21
21
  end
22
22
  end
@@ -9,7 +9,7 @@ require 'test/unit'
9
9
  class Test::Unit::TestCase
10
10
  AssertionFailedError = Test::Unit::AssertionFailedError rescue MiniTest::Assertion
11
11
  def assert_raise_with_message(e, message, &block)
12
- e = assert_raise(e, &block)
12
+ e = assert_raises(e, &block)
13
13
  if message.is_a?(Regexp)
14
14
  assert_match(message, e.message)
15
15
  else
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webmock
3
3
  version: !ruby/object:Gem::Version
4
- hash: 35
4
+ hash: 47
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 13
8
+ - 14
9
9
  - 0
10
- version: 1.13.0
10
+ version: 1.14.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Bartosz Blimke
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2013-07-05 00:00:00 Z
18
+ date: 2013-10-03 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: addressable