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.
- 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 [](http://travis-ci.org/bblimke/webmock) [](http://gemnasium.com/bblimke/webmock)
|
1
|
+
WebMock [](http://travis-ci.org/bblimke/webmock) [](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
|