webmock 1.5.0 → 1.6.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 +35 -0
- data/README.md +10 -24
- data/VERSION +1 -1
- data/lib/webmock.rb +4 -0
- data/lib/webmock/api.rb +1 -1
- data/lib/webmock/assertion_failure.rb +2 -4
- data/lib/webmock/cucumber.rb +8 -0
- data/lib/webmock/errors.rb +13 -1
- data/lib/webmock/http_lib_adapters/curb.rb +2 -2
- data/lib/webmock/http_lib_adapters/em_http_request.rb +31 -17
- data/lib/webmock/http_lib_adapters/httpclient.rb +3 -3
- data/lib/webmock/http_lib_adapters/net_http.rb +2 -2
- data/lib/webmock/http_lib_adapters/patron.rb +2 -2
- data/lib/webmock/request_execution_verifier.rb +18 -4
- data/lib/webmock/request_pattern.rb +1 -1
- data/lib/webmock/request_registry.rb +13 -28
- data/lib/webmock/request_signature.rb +15 -2
- data/lib/webmock/rspec.rb +32 -1
- data/lib/webmock/{adapters/rspec → rspec}/matchers.rb +4 -0
- data/lib/webmock/{adapters/rspec → rspec/matchers}/request_pattern_matcher.rb +0 -0
- data/lib/webmock/{adapters/rspec → rspec/matchers}/webmock_matcher.rb +0 -0
- data/lib/webmock/stub_registry.rb +43 -0
- data/lib/webmock/stub_request_snippet.rb +27 -0
- data/lib/webmock/test_unit.rb +20 -1
- data/lib/webmock/util/hash_counter.rb +9 -4
- data/lib/webmock/util/hash_keys_stringifier.rb +23 -0
- data/lib/webmock/webmock.rb +14 -4
- data/spec/curb_spec.rb +1 -1
- data/spec/curb_spec_helper.rb +0 -4
- data/spec/em_http_request_spec.rb +5 -0
- data/spec/em_http_request_spec_helper.rb +0 -4
- data/spec/errors_spec.rb +17 -0
- data/spec/httpclient_spec_helper.rb +0 -4
- data/spec/net_http_spec_helper.rb +2 -8
- data/spec/patron_spec_helper.rb +4 -11
- data/spec/request_execution_verifier_spec.rb +14 -4
- data/spec/request_registry_spec.rb +29 -80
- data/spec/request_signature_spec.rb +77 -3
- data/spec/spec_helper.rb +0 -18
- data/spec/stub_registry_spec.rb +86 -0
- data/spec/stub_request_snippet_spec.rb +47 -0
- data/spec/util/hash_counter_spec.rb +15 -0
- data/spec/util/hash_keys_stringifier_spec.rb +27 -0
- data/spec/webmock_shared.rb +63 -66
- data/test/test_helper.rb +5 -1
- data/test/test_webmock.rb +5 -2
- data/webmock.gemspec +17 -7
- metadata +19 -9
- data/lib/webmock/adapters/rspec.rb +0 -33
- data/lib/webmock/adapters/test_unit.rb +0 -19
@@ -2,7 +2,8 @@ module WebMock
|
|
2
2
|
|
3
3
|
class RequestSignature
|
4
4
|
|
5
|
-
attr_accessor :method, :uri, :body
|
5
|
+
attr_accessor :method, :uri, :body
|
6
|
+
attr_reader :headers
|
6
7
|
|
7
8
|
def initialize(method, uri, options = {})
|
8
9
|
self.method = method
|
@@ -20,11 +21,23 @@ module WebMock
|
|
20
21
|
string
|
21
22
|
end
|
22
23
|
|
24
|
+
def headers=(headers)
|
25
|
+
@headers = WebMock::Util::Headers.normalize_headers(headers)
|
26
|
+
end
|
27
|
+
|
28
|
+
def hash
|
29
|
+
self.to_s.hash
|
30
|
+
end
|
31
|
+
|
32
|
+
def eql?(other)
|
33
|
+
self.to_s == other.to_s
|
34
|
+
end
|
35
|
+
|
23
36
|
private
|
24
37
|
|
25
38
|
def assign_options(options)
|
26
39
|
self.body = options[:body] if options.has_key?(:body)
|
27
|
-
self.headers =
|
40
|
+
self.headers = options[:headers] if options.has_key?(:headers)
|
28
41
|
end
|
29
42
|
|
30
43
|
end
|
data/lib/webmock/rspec.rb
CHANGED
@@ -1 +1,32 @@
|
|
1
|
-
require
|
1
|
+
require 'webmock'
|
2
|
+
|
3
|
+
# RSpec 1.x and 2.x compatibility
|
4
|
+
if defined?(RSpec)
|
5
|
+
RSPEC_NAMESPACE = RSPEC_CONFIGURER = RSpec
|
6
|
+
elsif defined?(Spec)
|
7
|
+
RSPEC_NAMESPACE = Spec
|
8
|
+
RSPEC_CONFIGURER = Spec::Runner
|
9
|
+
else
|
10
|
+
begin
|
11
|
+
require 'rspec'
|
12
|
+
RSPEC_NAMESPACE = RSPEC_CONFIGURER = RSpec
|
13
|
+
rescue LoadError
|
14
|
+
require 'spec'
|
15
|
+
RSPEC_NAMESPACE = Spec
|
16
|
+
RSPEC_CONFIGURER = Spec::Runner
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'webmock/rspec/matchers'
|
21
|
+
|
22
|
+
RSPEC_CONFIGURER.configure { |config|
|
23
|
+
|
24
|
+
config.include WebMock::API
|
25
|
+
config.include WebMock::Matchers
|
26
|
+
|
27
|
+
config.after(:each) do
|
28
|
+
WebMock.reset!
|
29
|
+
end
|
30
|
+
}
|
31
|
+
|
32
|
+
WebMock::AssertionFailure.error_class = RSPEC_NAMESPACE::Expectations::ExpectationNotMetError
|
File without changes
|
File without changes
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module WebMock
|
2
|
+
|
3
|
+
class StubRegistry
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
attr_accessor :request_stubs
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
reset!
|
10
|
+
end
|
11
|
+
|
12
|
+
def reset!
|
13
|
+
self.request_stubs = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def register_request_stub(stub)
|
17
|
+
request_stubs.insert(0, stub)
|
18
|
+
stub
|
19
|
+
end
|
20
|
+
|
21
|
+
def registered_request?(request_signature)
|
22
|
+
request_stub_for(request_signature)
|
23
|
+
end
|
24
|
+
|
25
|
+
def response_for_request(request_signature)
|
26
|
+
stub = request_stub_for(request_signature)
|
27
|
+
stub ? evaluate_response_for_request(stub.response, request_signature) : nil
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def request_stub_for(request_signature)
|
33
|
+
request_stubs.detect { |registered_request_stub|
|
34
|
+
registered_request_stub.request_pattern.matches?(request_signature)
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def evaluate_response_for_request(response, request_signature)
|
39
|
+
response.evaluate(request_signature)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module WebMock
|
2
|
+
class StubRequestSnippet
|
3
|
+
def initialize(request_signature)
|
4
|
+
@request_signature = request_signature
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_s
|
8
|
+
string = "stub_request(:#{@request_signature.method},"
|
9
|
+
string << " \"#{WebMock::Util::URI.strip_default_port_from_uri_string(@request_signature.uri.to_s)}\")"
|
10
|
+
|
11
|
+
with = ""
|
12
|
+
|
13
|
+
if (@request_signature.body.to_s != '')
|
14
|
+
with << ":body => #{@request_signature.body.inspect}"
|
15
|
+
end
|
16
|
+
|
17
|
+
if (@request_signature.headers && !@request_signature.headers.empty?)
|
18
|
+
with << ", \n " unless with.empty?
|
19
|
+
|
20
|
+
with << ":headers => #{WebMock::Util::Headers.sorted_headers_string(@request_signature.headers)}"
|
21
|
+
end
|
22
|
+
string << ".\n with(#{with})" unless with.empty?
|
23
|
+
string << ".\n to_return(:status => 200, :body => \"\", :headers => {})"
|
24
|
+
string
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/webmock/test_unit.rb
CHANGED
@@ -1 +1,20 @@
|
|
1
|
-
require
|
1
|
+
require 'test/unit'
|
2
|
+
require 'webmock'
|
3
|
+
|
4
|
+
module Test
|
5
|
+
module Unit
|
6
|
+
class TestCase
|
7
|
+
include WebMock::API
|
8
|
+
|
9
|
+
alias_method :teardown_without_webmock, :teardown
|
10
|
+
def teardown_with_webmock
|
11
|
+
teardown_without_webmock
|
12
|
+
WebMock.reset!
|
13
|
+
end
|
14
|
+
alias_method :teardown, :teardown_with_webmock
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
WebMock::AssertionFailure.error_class = Test::Unit::AssertionFailedError rescue MiniTest::Assertion # ruby1.9 compat
|
@@ -1,20 +1,25 @@
|
|
1
1
|
module WebMock
|
2
|
-
|
3
2
|
module Util
|
4
|
-
|
5
3
|
class Util::HashCounter
|
6
4
|
attr_accessor :hash
|
7
5
|
def initialize
|
8
6
|
self.hash = {}
|
7
|
+
@order = {}
|
8
|
+
@max = 0
|
9
9
|
end
|
10
10
|
def put key, num=1
|
11
11
|
hash[key] = (hash[key] || 0) + num
|
12
|
+
@order[key] = @max = @max + 1
|
12
13
|
end
|
13
14
|
def get key
|
14
15
|
hash[key] || 0
|
15
16
|
end
|
16
|
-
end
|
17
17
|
|
18
|
+
def each(&block)
|
19
|
+
@order.to_a.sort {|a, b| a[1] <=> b[1]}.each do |a|
|
20
|
+
block.call(a[0], hash[a[0]])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
18
24
|
end
|
19
|
-
|
20
25
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module WebMock
|
2
|
+
module Util
|
3
|
+
class HashKeysStringifier
|
4
|
+
|
5
|
+
def self.stringify_keys!(arg)
|
6
|
+
case arg
|
7
|
+
when Array
|
8
|
+
arg.map { |elem| stringify_keys!(elem) }
|
9
|
+
when Hash
|
10
|
+
Hash[
|
11
|
+
*arg.map { |key, value|
|
12
|
+
k = key.is_a?(Symbol) ? key.to_s : key
|
13
|
+
v = stringify_keys!(value)
|
14
|
+
[k,v]
|
15
|
+
}.inject([]) {|r,x| r + x}]
|
16
|
+
else
|
17
|
+
arg
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/webmock/webmock.rb
CHANGED
@@ -48,20 +48,30 @@ module WebMock
|
|
48
48
|
Config.instance.allow && Config.instance.allow.include?(uri.host)
|
49
49
|
end
|
50
50
|
|
51
|
+
def self.reset!
|
52
|
+
WebMock::RequestRegistry.instance.reset!
|
53
|
+
WebMock::StubRegistry.instance.reset!
|
54
|
+
end
|
55
|
+
|
51
56
|
def self.reset_webmock
|
52
|
-
WebMock::
|
57
|
+
WebMock::Deprecation.warning("WebMock.reset_webmock is deprecated. Please use WebMock.reset! method instead")
|
58
|
+
reset!
|
53
59
|
end
|
54
|
-
|
60
|
+
|
55
61
|
def self.reset_callbacks
|
56
62
|
WebMock::CallbackRegistry.reset
|
57
63
|
end
|
58
64
|
|
59
65
|
def self.after_request(options={}, &block)
|
60
|
-
CallbackRegistry.add_callback(options, block)
|
66
|
+
WebMock::CallbackRegistry.add_callback(options, block)
|
61
67
|
end
|
62
68
|
|
63
69
|
def self.registered_request?(request_signature)
|
64
|
-
|
70
|
+
WebMock::StubRegistry.instance.registered_request?(request_signature)
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.print_executed_requests
|
74
|
+
puts WebMock::RequestExecutionVerifier.executed_requests_message
|
65
75
|
end
|
66
76
|
|
67
77
|
%w(
|
data/spec/curb_spec.rb
CHANGED
data/spec/curb_spec_helper.rb
CHANGED
@@ -25,5 +25,10 @@ unless RUBY_PLATFORM =~ /java/
|
|
25
25
|
http_request(:get, "http://www.example.com/?x=3", :query => {"a" => ["b", "c"]}).body.should == "abc"
|
26
26
|
end
|
27
27
|
|
28
|
+
it "should work with optional query params declared as string" do
|
29
|
+
stub_http_request(:get, "www.example.com/?x=3&a[]=b&a[]=c").to_return(:body => "abc")
|
30
|
+
http_request(:get, "http://www.example.com/?x=3", :query => "a[]=b&a[]=c").body.should == "abc"
|
31
|
+
end
|
32
|
+
|
28
33
|
end
|
29
34
|
end
|
data/spec/errors_spec.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "errors" do
|
4
|
+
describe WebMock::NetConnectNotAllowedError do
|
5
|
+
describe "message" do
|
6
|
+
it "should have message with request signature and snippet" do
|
7
|
+
request_signature = mock(:to_s => "aaa")
|
8
|
+
WebMock::StubRequestSnippet.stub!(:new).
|
9
|
+
with(request_signature).and_return(mock(:to_s => "bbb"))
|
10
|
+
expected = "Real HTTP connections are disabled. Unregistered request: aaa" +
|
11
|
+
"\n\nYou can stub this request with the following snippet:\n\n" +
|
12
|
+
"bbb\n\n============================================================"
|
13
|
+
WebMock::NetConnectNotAllowedError.new(request_signature).message.should == expected
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -41,10 +41,6 @@ module HTTPClientSpecHelper
|
|
41
41
|
Errno::ECONNREFUSED
|
42
42
|
end
|
43
43
|
|
44
|
-
def default_client_request_headers(request_method = nil, has_body = false)
|
45
|
-
{'Content-Type'=>'application/x-www-form-urlencoded'} if request_method == 'POST' && has_body
|
46
|
-
end
|
47
|
-
|
48
44
|
def setup_expectations_for_real_request(options = {})
|
49
45
|
socket = mock("TCPSocket")
|
50
46
|
TCPSocket.should_receive(:new).
|
@@ -22,7 +22,8 @@ module NetHTTPSpecHelper
|
|
22
22
|
http = Net::HTTP.new(uri.host, uri.port)
|
23
23
|
if uri.scheme == "https"
|
24
24
|
http.use_ssl = true
|
25
|
-
|
25
|
+
#1.9.1 has a bug with ssl_timeout
|
26
|
+
http.ssl_timeout = 10 unless RUBY_VERSION == "1.9.1"
|
26
27
|
end
|
27
28
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
28
29
|
response = http.start {|http|
|
@@ -38,13 +39,6 @@ module NetHTTPSpecHelper
|
|
38
39
|
})
|
39
40
|
end
|
40
41
|
|
41
|
-
def default_client_request_headers(request_method = nil, has_body = false)
|
42
|
-
default_request = Net::HTTPGenericRequest.new('','','','/')
|
43
|
-
default_net_http_headers = Hash[*default_request.to_hash.map {|k,v|
|
44
|
-
[k, v.flatten]
|
45
|
-
}.flatten]
|
46
|
-
end
|
47
|
-
|
48
42
|
def client_timeout_exception_class
|
49
43
|
Timeout::Error
|
50
44
|
end
|
data/spec/patron_spec_helper.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
1
3
|
module PatronSpecHelper
|
2
4
|
def http_request(method, uri, options = {}, &block)
|
3
5
|
uri = Addressable::URI.heuristic_parse(uri)
|
4
6
|
sess = Patron::Session.new
|
5
|
-
sess.base_url = "#{uri.omit(:userinfo, :query).normalize.to_s}".gsub(/\/$/,"")
|
6
|
-
|
7
|
+
sess.base_url = "#{uri.omit(:userinfo, :path, :query).normalize.to_s}".gsub(/\/$/,"")
|
7
8
|
sess.username = uri.user
|
8
9
|
sess.password = uri.password
|
9
10
|
|
10
11
|
sess.connect_timeout = 10
|
11
12
|
sess.timeout = 10
|
12
|
-
|
13
|
+
|
13
14
|
response = sess.request(method, "#{uri.path}#{uri.query ? '?' : ''}#{uri.query}", options[:headers] || {}, {
|
14
15
|
:data => options[:body]
|
15
16
|
})
|
@@ -28,14 +29,6 @@ module PatronSpecHelper
|
|
28
29
|
})
|
29
30
|
end
|
30
31
|
|
31
|
-
def default_client_request_headers(request_method = nil, has_body = false)
|
32
|
-
if Patron.version >= "0.4.6"
|
33
|
-
{'Expect'=>''}
|
34
|
-
else
|
35
|
-
nil
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
32
|
def client_timeout_exception_class
|
40
33
|
Patron::TimeoutError
|
41
34
|
end
|
@@ -5,6 +5,8 @@ describe WebMock::RequestExecutionVerifier do
|
|
5
5
|
@verifier = WebMock::RequestExecutionVerifier.new
|
6
6
|
@request_pattern = mock(WebMock::RequestPattern, :to_s => "www.example.com")
|
7
7
|
@verifier.request_pattern = @request_pattern
|
8
|
+
WebMock::RequestRegistry.instance.stub(:to_s).and_return("executed requests")
|
9
|
+
@executed_requests_info = "\n\nThe following requests were made:\n\nexecuted requests\n" + "="*60
|
8
10
|
end
|
9
11
|
|
10
12
|
|
@@ -13,13 +15,17 @@ describe WebMock::RequestExecutionVerifier do
|
|
13
15
|
it "should report failure message" do
|
14
16
|
@verifier.times_executed = 0
|
15
17
|
@verifier.expected_times_executed = 2
|
16
|
-
|
18
|
+
expected_text = "The request www.example.com was expected to execute 2 times but it executed 0 times"
|
19
|
+
expected_text << @executed_requests_info
|
20
|
+
@verifier.failure_message.should == expected_text
|
17
21
|
end
|
18
22
|
|
19
23
|
it "should report failure message correctly when executed times is one" do
|
20
24
|
@verifier.times_executed = 1
|
21
25
|
@verifier.expected_times_executed = 1
|
22
|
-
|
26
|
+
expected_text = "The request www.example.com was expected to execute 1 time but it executed 1 time"
|
27
|
+
expected_text << @executed_requests_info
|
28
|
+
@verifier.failure_message.should == expected_text
|
23
29
|
end
|
24
30
|
|
25
31
|
end
|
@@ -29,12 +35,16 @@ describe WebMock::RequestExecutionVerifier do
|
|
29
35
|
it "should report failure message if it executed number of times specified" do
|
30
36
|
@verifier.times_executed = 2
|
31
37
|
@verifier.expected_times_executed = 2
|
32
|
-
|
38
|
+
expected_text = "The request www.example.com was not expected to execute 2 times but it executed 2 times"
|
39
|
+
expected_text << @executed_requests_info
|
40
|
+
@verifier.negative_failure_message.should == expected_text
|
33
41
|
end
|
34
42
|
|
35
43
|
it "should report failure message when not expected request but it executed" do
|
36
44
|
@verifier.times_executed = 1
|
37
|
-
|
45
|
+
expected_text = "The request www.example.com was expected to execute 0 times but it executed 1 time"
|
46
|
+
expected_text << @executed_requests_info
|
47
|
+
@verifier.negative_failure_message.should == expected_text
|
38
48
|
end
|
39
49
|
|
40
50
|
end
|