webmock 1.13.0 → 1.14.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +30 -0
- data/README.md +12 -2
- data/lib/webmock/errors.rb +1 -1
- data/lib/webmock/http_lib_adapters/em_http_request/em_http_request_1_x.rb +0 -1
- data/lib/webmock/http_lib_adapters/excon_adapter.rb +1 -1
- data/lib/webmock/util/query_mapper.rb +5 -0
- data/lib/webmock/util/uri.rb +12 -3
- data/lib/webmock/version.rb +1 -1
- data/spec/acceptance/curb/curb_spec_helper.rb +1 -1
- data/spec/acceptance/em_http_request/em_http_request_spec.rb +17 -0
- data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +2 -2
- data/spec/acceptance/shared/callbacks.rb +5 -5
- data/spec/acceptance/shared/stubbing_requests.rb +9 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support/network_connection.rb +1 -1
- data/spec/unit/errors_spec.rb +28 -10
- data/spec/unit/request_execution_verifier_spec.rb +1 -1
- data/spec/unit/response_spec.rb +3 -3
- data/spec/unit/util/uri_spec.rb +13 -0
- data/test/shared_test.rb +2 -2
- data/test/test_helper.rb +1 -1
- metadata +4 -4
data/CHANGELOG.md
CHANGED
@@ -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)
|
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
|
-
|
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.
|
data/lib/webmock/errors.rb
CHANGED
@@ -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,
|
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
|
data/lib/webmock/util/uri.rb
CHANGED
@@ -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|
|
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|
|
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|
|
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
|
data/lib/webmock/version.rb
CHANGED
@@ -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://
|
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://
|
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 ==
|
109
|
-
@response.status[1].should == "
|
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 == "
|
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 ==
|
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"
|
data/spec/spec_helper.rb
CHANGED
@@ -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
|
data/spec/unit/errors_spec.rb
CHANGED
@@ -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 =
|
8
|
-
request_stub =
|
9
|
-
WebMock::RequestStub.stub
|
10
|
-
WebMock::StubRequestSnippet.stub
|
11
|
-
with(request_stub).and_return(
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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 =
|
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
|
data/spec/unit/response_spec.rb
CHANGED
@@ -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 =
|
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 =
|
16
|
-
WebMock::DynamicResponse.should_receive(:new).with(callable).and_return(@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
|
|
data/spec/unit/util/uri_spec.rb
CHANGED
@@ -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
|
data/test/shared_test.rb
CHANGED
@@ -10,13 +10,13 @@ module SharedTest
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_assert_requested_with_stub_and_block_raises_error
|
13
|
-
|
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
|
-
|
19
|
+
assert_raises ArgumentError do
|
20
20
|
assert_not_requested(@stub_http) {}
|
21
21
|
end
|
22
22
|
end
|
data/test/test_helper.rb
CHANGED
@@ -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 =
|
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:
|
4
|
+
hash: 47
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
8
|
+
- 14
|
9
9
|
- 0
|
10
|
-
version: 1.
|
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-
|
18
|
+
date: 2013-10-03 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: addressable
|