webmock 1.6.4 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
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