webmock 1.6.4 → 1.7.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 (95) hide show
  1. data/.gemtest +0 -0
  2. data/.gitignore +3 -1
  3. data/.travis.yml +6 -0
  4. data/CHANGELOG.md +211 -118
  5. data/Gemfile +16 -1
  6. data/Guardfile +24 -0
  7. data/LICENSE +1 -1
  8. data/README.md +64 -15
  9. data/Rakefile +19 -6
  10. data/lib/webmock.rb +9 -4
  11. data/lib/webmock/api.rb +5 -4
  12. data/lib/webmock/assertion_failure.rb +1 -1
  13. data/lib/webmock/callback_registry.rb +1 -1
  14. data/lib/webmock/config.rb +2 -2
  15. data/lib/webmock/cucumber.rb +1 -1
  16. data/lib/webmock/errors.rb +17 -5
  17. data/lib/webmock/http_lib_adapters/{curb.rb → curb_adapter.rb} +79 -49
  18. data/lib/webmock/http_lib_adapters/{em_http_request.rb → em_http_request/em_http_request_0_x.rb} +20 -15
  19. data/lib/webmock/http_lib_adapters/em_http_request/em_http_request_1_x.rb +201 -0
  20. data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +11 -0
  21. data/lib/webmock/http_lib_adapters/http_lib_adapter.rb +7 -0
  22. data/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +19 -0
  23. data/lib/webmock/http_lib_adapters/{httpclient.rb → httpclient_adapter.rb} +35 -8
  24. data/lib/webmock/http_lib_adapters/net_http.rb +84 -25
  25. data/lib/webmock/http_lib_adapters/net_http_response.rb +17 -17
  26. data/lib/webmock/http_lib_adapters/patron_adapter.rb +124 -0
  27. data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +166 -0
  28. data/lib/webmock/minitest.rb +15 -0
  29. data/lib/webmock/rack_response.rb +52 -0
  30. data/lib/webmock/request_pattern.rb +4 -2
  31. data/lib/webmock/request_signature.rb +4 -0
  32. data/lib/webmock/request_stub.rb +35 -2
  33. data/lib/webmock/responses_sequence.rb +2 -2
  34. data/lib/webmock/rspec.rb +2 -2
  35. data/lib/webmock/rspec/matchers.rb +9 -4
  36. data/lib/webmock/rspec/matchers/webmock_matcher.rb +1 -1
  37. data/lib/webmock/stub_registry.rb +1 -1
  38. data/lib/webmock/stub_request_snippet.rb +14 -11
  39. data/lib/webmock/util/hash_keys_stringifier.rb +4 -4
  40. data/lib/webmock/util/headers.rb +3 -3
  41. data/lib/webmock/util/json.rb +54 -0
  42. data/lib/webmock/util/uri.rb +1 -1
  43. data/lib/webmock/version.rb +1 -1
  44. data/lib/webmock/webmock.rb +20 -3
  45. data/minitest/test_helper.rb +29 -0
  46. data/minitest/test_webmock.rb +6 -0
  47. data/minitest/webmock_spec.rb +30 -0
  48. data/spec/curb_spec.rb +26 -8
  49. data/spec/curb_spec_helper.rb +6 -6
  50. data/spec/em_http_request_spec.rb +95 -1
  51. data/spec/em_http_request_spec_helper.rb +16 -16
  52. data/spec/errors_spec.rb +19 -4
  53. data/spec/example_curl_output.txt +22 -22
  54. data/spec/http_lib_adapters/http_lib_adapter_registry_spec.rb +17 -0
  55. data/spec/http_lib_adapters/http_lib_adapter_spec.rb +12 -0
  56. data/spec/httpclient_spec.rb +1 -1
  57. data/spec/httpclient_spec_helper.rb +3 -38
  58. data/spec/my_rack_app.rb +18 -0
  59. data/spec/net_http_shared.rb +125 -0
  60. data/spec/net_http_spec.rb +27 -31
  61. data/spec/net_http_spec_helper.rb +4 -34
  62. data/spec/network_connection.rb +1 -1
  63. data/spec/patron_spec_helper.rb +4 -7
  64. data/spec/quality_spec.rb +60 -0
  65. data/spec/rack_response_spec.rb +33 -0
  66. data/spec/real_net_http_spec.rb +20 -0
  67. data/spec/request_execution_verifier_spec.rb +8 -8
  68. data/spec/request_pattern_spec.rb +3 -3
  69. data/spec/request_stub_spec.rb +19 -19
  70. data/spec/response_spec.rb +8 -8
  71. data/spec/spec_helper.rb +14 -11
  72. data/spec/stub_request_snippet_spec.rb +85 -37
  73. data/spec/support/webmock_server.rb +62 -0
  74. data/spec/typhoeus_hydra_spec.rb +53 -0
  75. data/spec/typhoeus_hydra_spec_helper.rb +50 -0
  76. data/spec/util/headers_spec.rb +5 -5
  77. data/spec/util/json_spec.rb +7 -0
  78. data/spec/util/uri_spec.rb +1 -1
  79. data/spec/vendor/addressable/lib/uri.rb +1 -0
  80. data/spec/vendor/crack/lib/crack.rb +1 -0
  81. data/spec/vendor/right_http_connection-1.2.4/History.txt +4 -4
  82. data/spec/vendor/right_http_connection-1.2.4/README.txt +4 -4
  83. data/spec/vendor/right_http_connection-1.2.4/Rakefile +3 -3
  84. data/spec/vendor/right_http_connection-1.2.4/lib/net_fix.rb +4 -4
  85. data/spec/vendor/right_http_connection-1.2.4/setup.rb +4 -4
  86. data/spec/webmock_shared.rb +375 -143
  87. data/spec/webmock_spec.rb +7 -0
  88. data/test/http_request.rb +24 -0
  89. data/test/shared_test.rb +47 -0
  90. data/test/test_helper.rb +6 -3
  91. data/test/test_webmock.rb +2 -67
  92. data/webmock.gemspec +8 -7
  93. metadata +153 -88
  94. data/lib/webmock/http_lib_adapters/patron.rb +0 -100
  95. data/spec/other_net_http_libs_spec.rb +0 -30
@@ -1,5 +1,5 @@
1
1
  module WebMock
2
-
2
+
3
3
  class ResponsesSequence
4
4
 
5
5
  attr_accessor :times_to_repeat
@@ -36,5 +36,5 @@ module WebMock
36
36
  end
37
37
 
38
38
  end
39
-
39
+
40
40
  end
data/lib/webmock/rspec.rb CHANGED
@@ -6,7 +6,7 @@ if defined?(RSpec) && defined?(RSpec::Expectations)
6
6
  elsif defined?(Spec)
7
7
  RSPEC_NAMESPACE = Spec
8
8
  RSPEC_CONFIGURER = Spec::Runner
9
- else
9
+ else
10
10
  begin
11
11
  require 'rspec/core'
12
12
  require 'rspec/expectations'
@@ -19,7 +19,7 @@ else
19
19
  end
20
20
 
21
21
  require 'webmock/rspec/matchers'
22
-
22
+
23
23
  RSPEC_CONFIGURER.configure { |config|
24
24
 
25
25
  config.include WebMock::API
@@ -7,17 +7,22 @@ module WebMock
7
7
  def have_been_made
8
8
  WebMock::RequestPatternMatcher.new
9
9
  end
10
-
10
+
11
+ def have_been_requested
12
+ WebMock::RequestPatternMatcher.new
13
+ end
14
+
15
+
11
16
  def have_not_been_made
12
17
  WebMock::RequestPatternMatcher.new.times(0)
13
18
  end
14
-
19
+
15
20
  def have_requested(method, uri)
16
21
  WebMock::WebMockMatcher.new(method, uri)
17
22
  end
18
-
23
+
19
24
  def have_not_requested(method, uri)
20
25
  WebMock::WebMockMatcher.new(method, uri).times(0)
21
26
  end
22
27
  end
23
- end
28
+ end
@@ -29,7 +29,7 @@ module WebMock
29
29
  def matches?(webmock)
30
30
  @request_execution_verifier.matches?
31
31
  end
32
-
32
+
33
33
  def does_not_match?(webmock)
34
34
  @request_execution_verifier.does_not_match?
35
35
  end
@@ -40,4 +40,4 @@ module WebMock
40
40
  end
41
41
 
42
42
  end
43
- end
43
+ end
@@ -1,26 +1,29 @@
1
1
  module WebMock
2
2
  class StubRequestSnippet
3
- def initialize(request_signature)
4
- @request_signature = request_signature
3
+ def initialize(request_stub)
4
+ @request_stub = request_stub
5
5
  end
6
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)}\")"
7
+ def to_s(with_response = true)
8
+ request_pattern = @request_stub.request_pattern
9
+ string = "stub_request(:#{request_pattern.method_pattern.to_s},"
10
+ string << " \"#{request_pattern.uri_pattern.to_s}\")"
10
11
 
11
12
  with = ""
12
13
 
13
- if (@request_signature.body.to_s != '')
14
- with << ":body => #{@request_signature.body.inspect}"
14
+ if (request_pattern.body_pattern)
15
+ with << ":body => #{request_pattern.body_pattern.to_s}"
15
16
  end
16
17
 
17
- if (@request_signature.headers && !@request_signature.headers.empty?)
18
- with << ", \n " unless with.empty?
18
+ if (request_pattern.headers_pattern)
19
+ with << ",\n " unless with.empty?
19
20
 
20
- with << ":headers => #{WebMock::Util::Headers.sorted_headers_string(@request_signature.headers)}"
21
+ with << ":headers => #{request_pattern.headers_pattern.to_s}"
21
22
  end
22
23
  string << ".\n with(#{with})" unless with.empty?
23
- string << ".\n to_return(:status => 200, :body => \"\", :headers => {})"
24
+ if with_response
25
+ string << ".\n to_return(:status => 200, :body => \"\", :headers => {})"
26
+ end
24
27
  string
25
28
  end
26
29
  end
@@ -1,14 +1,14 @@
1
1
  module WebMock
2
2
  module Util
3
3
  class HashKeysStringifier
4
-
4
+
5
5
  def self.stringify_keys!(arg)
6
6
  case arg
7
7
  when Array
8
8
  arg.map { |elem| stringify_keys!(elem) }
9
9
  when Hash
10
10
  Hash[
11
- *arg.map { |key, value|
11
+ *arg.map { |key, value|
12
12
  k = key.is_a?(Symbol) ? key.to_s : key
13
13
  v = stringify_keys!(value)
14
14
  [k,v]
@@ -17,7 +17,7 @@ module WebMock
17
17
  arg
18
18
  end
19
19
  end
20
-
20
+
21
21
  end
22
22
  end
23
- end
23
+ end
@@ -26,12 +26,12 @@ module WebMock
26
26
  when Regexp then v.inspect
27
27
  when Array then "["+v.map{|v| "'#{v.to_s}'"}.join(", ")+"]"
28
28
  else "'#{v.to_s}'"
29
- end
29
+ end
30
30
  "'#{k}'=>#{v}"
31
- end.sort.join(", ")
31
+ end.sort.join(", ")
32
32
  str << '}'
33
33
  end
34
-
34
+
35
35
  def self.decode_userinfo_from_header(header)
36
36
  header.sub(/^Basic /, "").unpack("m").first
37
37
  end
@@ -0,0 +1,54 @@
1
+ # This is a copy of https://github.com/jnunemaker/crack/blob/master/lib/crack/json.rb
2
+ # with date parsing removed
3
+ module WebMock
4
+ module Util
5
+ class JSON
6
+ def self.parse(json)
7
+ YAML.load(unescape(convert_json_to_yaml(json)))
8
+ rescue ArgumentError => e
9
+ raise ParseError, "Invalid JSON string"
10
+ end
11
+
12
+ protected
13
+ def self.unescape(str)
14
+ str.gsub(/\\u([0-9a-f]{4})/) { [$1.hex].pack("U") }
15
+ end
16
+
17
+ # Ensure that ":" and "," are always followed by a space
18
+ def self.convert_json_to_yaml(json) #:nodoc:
19
+ scanner, quoting, marks, pos, times = StringScanner.new(json), false, [], nil, []
20
+ while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/)
21
+ case char = scanner[1]
22
+ when '"', "'"
23
+ if !quoting
24
+ quoting = char
25
+ pos = scanner.pos
26
+ elsif quoting == char
27
+ quoting = false
28
+ end
29
+ when ":",","
30
+ marks << scanner.pos - 1 unless quoting
31
+ when "\\"
32
+ scanner.skip(/\\/)
33
+ end
34
+ end
35
+
36
+ if marks.empty?
37
+ json.gsub(/\\\//, '/')
38
+ else
39
+ left_pos = [-1].push(*marks)
40
+ right_pos = marks << json.length
41
+ output = []
42
+ left_pos.each_with_index do |left, i|
43
+ output << json[left.succ..right_pos[i]]
44
+ end
45
+ output = output * " "
46
+
47
+ times.each { |i| output[i-1] = ' ' }
48
+ output.gsub!(/\\\//, '/')
49
+ output
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -67,7 +67,7 @@ module WebMock
67
67
  end
68
68
 
69
69
  def self.is_uri_localhost?(uri)
70
- uri.is_a?(Addressable::URI) &&
70
+ uri.is_a?(Addressable::URI) &&
71
71
  %w(localhost 127.0.0.1 0.0.0.0).include?(uri.host)
72
72
  end
73
73
 
@@ -1,3 +1,3 @@
1
1
  module WebMock
2
- VERSION = '1.6.4'
2
+ VERSION = '1.7.0' unless defined?(::WebMock::VERSION)
3
3
  end
@@ -25,6 +25,22 @@ module WebMock
25
25
  VERSION
26
26
  end
27
27
 
28
+ def self.disable!(options = {})
29
+ except = [options[:except]].flatten.compact
30
+ HttpLibAdapterRegistry.instance.each_adapter do |name, adapter|
31
+ adapter.enable!
32
+ adapter.disable! unless except.include?(name)
33
+ end
34
+ end
35
+
36
+ def self.enable!(options = {})
37
+ except = [options[:except]].flatten.compact
38
+ HttpLibAdapterRegistry.instance.each_adapter do |name, adapter|
39
+ adapter.disable!
40
+ adapter.enable! unless except.include?(name)
41
+ end
42
+ end
43
+
28
44
  def self.allow_net_connect!(options = {})
29
45
  Config.instance.allow_net_connect = true
30
46
  Config.instance.net_http_connect_on_start = options[:net_http_connect_on_start]
@@ -43,19 +59,19 @@ module WebMock
43
59
  end
44
60
  Config.instance.allow_net_connect ||
45
61
  (Config.instance.allow_localhost && WebMock::Util::URI.is_uri_localhost?(uri)) ||
46
- Config.instance.allow && Config.instance.allow.include?(uri.host)
62
+ Config.instance.allow && (Config.instance.allow.include?(uri.host) || Config.instance.allow.include?("#{uri.host}:#{uri.port}"))
47
63
  end
48
64
 
49
65
  def self.reset!
50
66
  WebMock::RequestRegistry.instance.reset!
51
67
  WebMock::StubRegistry.instance.reset!
52
68
  end
53
-
69
+
54
70
  def self.reset_webmock
55
71
  WebMock::Deprecation.warning("WebMock.reset_webmock is deprecated. Please use WebMock.reset! method instead")
56
72
  reset!
57
73
  end
58
-
74
+
59
75
  def self.reset_callbacks
60
76
  WebMock::CallbackRegistry.reset
61
77
  end
@@ -89,4 +105,5 @@ module WebMock
89
105
  ))
90
106
  end
91
107
 
108
+ self.enable!
92
109
  end
@@ -0,0 +1,29 @@
1
+ require 'rubygems'
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+
6
+ require File.expand_path(File.dirname(__FILE__) + '/../test/http_request')
7
+
8
+ gem "minitest"
9
+ require 'minitest/autorun'
10
+ require 'webmock/minitest'
11
+
12
+ class MiniTest::Unit::TestCase
13
+ def assert_raise(*exp, &block)
14
+ assert_raises(*exp, &block)
15
+ end
16
+
17
+ def assert_raise_with_message(e, message, &block)
18
+ e = assert_raises(e, &block)
19
+ if message.is_a?(Regexp)
20
+ assert_match(message, e.message)
21
+ else
22
+ assert_equal(message, e.message)
23
+ end
24
+ end
25
+
26
+ def assert_fail(message, &block)
27
+ assert_raise_with_message(MiniTest::Assertion, message, &block)
28
+ end
29
+ end
@@ -0,0 +1,6 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
+ require File.expand_path(File.dirname(__FILE__) + '/../test/shared_test')
3
+
4
+ class MiniTestWebMock < MiniTest::Unit::TestCase
5
+ include SharedTest
6
+ end
@@ -0,0 +1,30 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
+
3
+ describe "Webmock" do
4
+ include HttpRequestTestHelper
5
+
6
+ before do
7
+ stub_http_request(:any, "http://www.example.com")
8
+ stub_http_request(:any, "https://www.example.com")
9
+ end
10
+
11
+ it "should raise error on non stubbed request" do
12
+ lambda { http_request(:get, "http://www.example.net/") }.must_raise(WebMock::NetConnectNotAllowedError)
13
+ end
14
+
15
+ it "should verify that expected request occured" do
16
+ http_request(:get, "http://www.example.com/")
17
+ assert_requested(:get, "http://www.example.com", :times => 1)
18
+ assert_requested(:get, "http://www.example.com")
19
+ end
20
+
21
+ it "should verify that expect request didn't occur" do
22
+ expected_message = "The request GET http://www.example.com/ was expected to execute 1 time but it executed 0 times"
23
+ expected_message << "\n\nThe following requests were made:\n\nNo requests were made.\n============================================================"
24
+ assert_fail(expected_message) do
25
+ assert_requested(:get, "http://www.example.com")
26
+ end
27
+ end
28
+
29
+ end
30
+
data/spec/curb_spec.rb CHANGED
@@ -6,7 +6,7 @@ unless RUBY_PLATFORM =~ /java/
6
6
 
7
7
  shared_examples_for "Curb" do
8
8
  include CurbSpecHelper
9
-
9
+
10
10
  it_should_behave_like "WebMock"
11
11
 
12
12
  describe "when doing PUTs" do
@@ -35,7 +35,7 @@ unless RUBY_PLATFORM =~ /java/
35
35
  stub_request(:any, "example.com").to_return(:body => body)
36
36
 
37
37
  test = nil
38
- @curl.on_success do |c|
38
+ @curl.on_success do |c|
39
39
  test = c.body_str
40
40
  end
41
41
  @curl.http_get
@@ -48,7 +48,7 @@ unless RUBY_PLATFORM =~ /java/
48
48
  to_return(:status => [response_code, "Server On Fire"])
49
49
 
50
50
  test = nil
51
- @curl.on_failure do |c, code|
51
+ @curl.on_failure do |c, code|
52
52
  test = code
53
53
  end
54
54
  @curl.http_get
@@ -61,19 +61,19 @@ unless RUBY_PLATFORM =~ /java/
61
61
  to_return(:body => body)
62
62
 
63
63
  test = nil
64
- @curl.on_body do |data|
64
+ @curl.on_body do |data|
65
65
  test = data
66
66
  end
67
67
  @curl.http_get
68
68
  test.should == body
69
69
  end
70
-
70
+
71
71
  it "should call on_header when response headers are read" do
72
72
  stub_request(:any, "example.com").
73
73
  to_return(:headers => {:one => 1})
74
74
 
75
75
  test = nil
76
- @curl.on_header do |data|
76
+ @curl.on_header do |data|
77
77
  test = data
78
78
  end
79
79
  @curl.http_get
@@ -119,7 +119,7 @@ unless RUBY_PLATFORM =~ /java/
119
119
  order.should == [:on_progress,:on_header,:on_body,:on_complete,:on_success]
120
120
  end
121
121
 
122
- it "should call callbacks in correct order on successful request" do
122
+ it "should call callbacks in correct order on failed request" do
123
123
  stub_request(:any, "example.com").to_return(:status => [500, ""])
124
124
  order = []
125
125
  @curl.on_success {|*args| order << :on_success }
@@ -217,7 +217,7 @@ unless RUBY_PLATFORM =~ /java/
217
217
  end
218
218
  end
219
219
  end
220
-
220
+
221
221
  describe "#content_type" do
222
222
  before(:each) do
223
223
  @curl = Curl::Easy.new
@@ -281,6 +281,12 @@ unless RUBY_PLATFORM =~ /java/
281
281
  c.response_code.should == 200
282
282
  end
283
283
 
284
+ it "should work with several body arguments for post using the class method" do
285
+ stub_http_request(:post, "www.example.com").with(:user => {:first_name=>'Bartosz', :last_name=>'Blimke'})
286
+ c = Curl::Easy.http_post "http://www.example.com", 'user[first_name]=Bartosz', 'user[last_name]=Blimke'
287
+ c.response_code.should == 200
288
+ end
289
+
284
290
  it "should work with blank arguments for put" do
285
291
  stub_http_request(:put, "www.example.com").with(:body => "01234")
286
292
  c = Curl::Easy.new
@@ -289,6 +295,18 @@ unless RUBY_PLATFORM =~ /java/
289
295
  c.http_put
290
296
  c.response_code.should == 200
291
297
  end
298
+
299
+ it "should work with multiple arguments for post" do
300
+ data = { :name => "john", :address => "111 example ave" }
301
+
302
+ stub_http_request(:post, "www.example.com").with(:body => data)
303
+ c = Curl::Easy.new
304
+ c.url = "http://www.example.com"
305
+ c.http_post Curl::PostField.content('name', data[:name]), Curl::PostField.content('address', data[:address])
306
+
307
+ c.response_code.should == 200
308
+ end
309
+
292
310
  end
293
311
 
294
312
  describe "using #perform for requests" do