webmock 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/.gitignore +21 -0
  2. data/LICENSE +281 -0
  3. data/README.md +170 -0
  4. data/Rakefile +54 -0
  5. data/VERSION +1 -0
  6. data/lib/webmock.rb +18 -0
  7. data/lib/webmock/adapters/rspec.rb +23 -0
  8. data/lib/webmock/adapters/rspec/matchers.rb +19 -0
  9. data/lib/webmock/adapters/rspec/request_profile_matcher.rb +37 -0
  10. data/lib/webmock/adapters/rspec/webmock_matcher.rb +45 -0
  11. data/lib/webmock/adapters/test_unit.rb +25 -0
  12. data/lib/webmock/config.rb +7 -0
  13. data/lib/webmock/errors.rb +5 -0
  14. data/lib/webmock/http_lib_adapters/net_http.rb +129 -0
  15. data/lib/webmock/request_execution_verifier.rb +22 -0
  16. data/lib/webmock/request_profile.rb +67 -0
  17. data/lib/webmock/request_registry.rb +47 -0
  18. data/lib/webmock/request_stub.rb +26 -0
  19. data/lib/webmock/response.rb +31 -0
  20. data/lib/webmock/url.rb +46 -0
  21. data/lib/webmock/util/hash_counter.rb +12 -0
  22. data/lib/webmock/utility.rb +65 -0
  23. data/lib/webmock/webmock.rb +58 -0
  24. data/spec/net_http_spec.rb +33 -0
  25. data/spec/other_net_http_libs_spec.rb +37 -0
  26. data/spec/request_execution_verifier_spec.rb +51 -0
  27. data/spec/request_profile_spec.rb +166 -0
  28. data/spec/request_registry_spec.rb +114 -0
  29. data/spec/request_stub_spec.rb +54 -0
  30. data/spec/response_spec.rb +59 -0
  31. data/spec/spec.opts +1 -0
  32. data/spec/spec_helper.rb +58 -0
  33. data/spec/util/hash_counter_spec.rb +24 -0
  34. data/spec/utility_spec.rb +70 -0
  35. data/spec/vendor/right_http_connection-1.2.4/History.txt +59 -0
  36. data/spec/vendor/right_http_connection-1.2.4/Manifest.txt +7 -0
  37. data/spec/vendor/right_http_connection-1.2.4/README.txt +54 -0
  38. data/spec/vendor/right_http_connection-1.2.4/Rakefile +103 -0
  39. data/spec/vendor/right_http_connection-1.2.4/lib/net_fix.rb +160 -0
  40. data/spec/vendor/right_http_connection-1.2.4/lib/right_http_connection.rb +435 -0
  41. data/spec/vendor/right_http_connection-1.2.4/setup.rb +1585 -0
  42. data/spec/vendor/samuel-0.2.1/.document +5 -0
  43. data/spec/vendor/samuel-0.2.1/.gitignore +5 -0
  44. data/spec/vendor/samuel-0.2.1/LICENSE +20 -0
  45. data/spec/vendor/samuel-0.2.1/README.rdoc +70 -0
  46. data/spec/vendor/samuel-0.2.1/Rakefile +62 -0
  47. data/spec/vendor/samuel-0.2.1/VERSION +1 -0
  48. data/spec/vendor/samuel-0.2.1/lib/samuel.rb +52 -0
  49. data/spec/vendor/samuel-0.2.1/lib/samuel/net_http.rb +10 -0
  50. data/spec/vendor/samuel-0.2.1/lib/samuel/request.rb +96 -0
  51. data/spec/vendor/samuel-0.2.1/samuel.gemspec +69 -0
  52. data/spec/vendor/samuel-0.2.1/test/request_test.rb +193 -0
  53. data/spec/vendor/samuel-0.2.1/test/samuel_test.rb +42 -0
  54. data/spec/vendor/samuel-0.2.1/test/test_helper.rb +66 -0
  55. data/spec/vendor/samuel-0.2.1/test/thread_test.rb +32 -0
  56. data/spec/webmock_spec.rb +492 -0
  57. data/test/test_helper.rb +9 -0
  58. data/test/test_webmock.rb +56 -0
  59. metadata +144 -0
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "webmock"
8
+ gem.summary = %Q{Library for stubbing HTTP requests in Ruby.}
9
+ gem.description = %Q{WebMock allows stubbing HTTP requests and setting expectations on HTTP requests.}
10
+ gem.email = "bartosz.blimke@gmail.com"
11
+ gem.homepage = "http://github.com/bblimke/webmock"
12
+ gem.authors = ["Bartosz Blimke"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'spec/rake/spectask'
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.spec_files = FileList['spec/**/*_spec.rb'].exclude("spec/vendor")
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ spec.rcov = true
31
+ end
32
+
33
+ require 'rake/testtask'
34
+ Rake::TestTask.new(:test) do |test|
35
+ test.test_files = FileList["test/**/*.rb"].exclude("test/test_helper.rb")
36
+ test.verbose = false
37
+ test.warning = true
38
+ end
39
+
40
+ task :spec => :check_dependencies
41
+
42
+ task :test => :check_dependencies
43
+
44
+ task :default => [:spec, :test]
45
+
46
+ require 'rake/rdoctask'
47
+ Rake::RDocTask.new do |rdoc|
48
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
49
+
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = "webmock #{version}"
52
+ rdoc.rdoc_files.include('README*')
53
+ rdoc.rdoc_files.include('lib/webmock/webmock.rb')
54
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.7.0
@@ -0,0 +1,18 @@
1
+ require 'singleton'
2
+
3
+ require 'webmock/http_lib_adapters/net_http'
4
+
5
+ require 'webmock/errors'
6
+ require 'webmock/request_profile'
7
+ require 'webmock/request_execution_verifier'
8
+ require 'webmock/url'
9
+ require 'webmock/request_stub'
10
+ require 'webmock/utility'
11
+ require 'webmock/config'
12
+ require 'webmock/response'
13
+ require 'webmock/util/hash_counter'
14
+ require 'webmock/request_registry'
15
+ require 'webmock/webmock'
16
+
17
+ require 'webmock/adapters/rspec'
18
+ require 'webmock/adapters/test_unit'
@@ -0,0 +1,23 @@
1
+ if defined?(Spec::Runner)
2
+
3
+ require 'webmock/adapters/rspec/request_profile_matcher'
4
+ require 'webmock/adapters/rspec/webmock_matcher'
5
+ require 'webmock/adapters/rspec/matchers'
6
+
7
+ Spec::Runner.configure { |config|
8
+
9
+ config.include WebMock::Matchers
10
+
11
+ config.before :each do
12
+ WebMock.reset_webmock
13
+ end
14
+ }
15
+
16
+ module WebMock
17
+ private
18
+ def assertion_failure(message)
19
+ raise Spec::Expectations::ExpectationNotMetError.new(message)
20
+ end
21
+ end
22
+
23
+ end
@@ -0,0 +1,19 @@
1
+ module WebMock
2
+ module Matchers
3
+ def have_been_made
4
+ WebMock::RequestProfileMatcher.new
5
+ end
6
+
7
+ def have_not_been_made
8
+ WebMock::RequestProfileMatcher.new.times(0)
9
+ end
10
+
11
+ def have_requested(method, url)
12
+ WebMock::WebMockMatcher.new(method, url)
13
+ end
14
+
15
+ def have_not_requested(method, url)
16
+ WebMock::WebMockMatcher.new(method, url).times(0)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,37 @@
1
+ module WebMock
2
+ class RequestProfileMatcher
3
+
4
+ def initialize
5
+ @request_execution_verifier = RequestExecutionVerifier.new
6
+ end
7
+
8
+ def once
9
+ @request_execution_verifier.expected_times_executed = 1
10
+ self
11
+ end
12
+
13
+ def twice
14
+ @request_execution_verifier.expected_times_executed = 2
15
+ self
16
+ end
17
+
18
+ def times(times)
19
+ @request_execution_verifier.expected_times_executed = times.to_i
20
+ self
21
+ end
22
+
23
+ def matches?(request_profile)
24
+ @request_execution_verifier.request_profile = request_profile
25
+ @request_execution_verifier.verify
26
+ end
27
+
28
+ def failure_message
29
+ @request_execution_verifier.failure_message
30
+ end
31
+
32
+
33
+ def negative_failure_message
34
+ @request_execution_verifier.negative_failure_message
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,45 @@
1
+ module WebMock
2
+ class WebMockMatcher
3
+
4
+ def initialize(method, url)
5
+ @request_execution_verifier = RequestExecutionVerifier.new
6
+ @request_execution_verifier.request_profile = RequestProfile.new(method, url)
7
+ end
8
+
9
+ def once
10
+ @request_execution_verifier.expected_times_executed = 1
11
+ self
12
+ end
13
+
14
+ def twice
15
+ @request_execution_verifier.expected_times_executed = 2
16
+ self
17
+ end
18
+
19
+ def with(options)
20
+ @request_execution_verifier.request_profile.body =
21
+ options[:body] if options.has_key?(:body)
22
+ @request_execution_verifier.request_profile.headers =
23
+ options[:headers] if options.has_key?(:headers)
24
+ self
25
+ end
26
+
27
+ def times(times)
28
+ @request_execution_verifier.expected_times_executed = times.to_i
29
+ self
30
+ end
31
+
32
+ def matches?(webmock)
33
+ @request_execution_verifier.verify
34
+ end
35
+
36
+ def failure_message
37
+ @request_execution_verifier.failure_message
38
+ end
39
+
40
+
41
+ def negative_failure_message
42
+ @request_execution_verifier.negative_failure_message
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,25 @@
1
+ if defined?(Test::Unit::TestCase)
2
+
3
+ class Test::Unit::TestCase
4
+ include WebMock
5
+ alias setup_without_webmock setup
6
+ def setup
7
+ reset_webmock
8
+ @original_allow_net_connect = WebMock.net_connect_allowed?
9
+ WebMock.disable_net_connect!
10
+ end
11
+
12
+ alias teardown_without_webmock teardown
13
+ def teardown
14
+ @original_allow_net_connect ? WebMock.allow_net_connect! : WebMock.disable_net_connect!
15
+ end
16
+ end
17
+
18
+ module WebMock
19
+ private
20
+ def assertion_failure(message)
21
+ raise Test::Unit::AssertionFailedError.new(message)
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,7 @@
1
+ module WebMock
2
+ class Config
3
+ include Singleton
4
+
5
+ attr_accessor :allow_net_connect
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ module WebMock
2
+
3
+ class NetConnectNotAllowedError < StandardError; end;
4
+
5
+ end
@@ -0,0 +1,129 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'stringio'
4
+
5
+
6
+ class StubSocket #:nodoc:
7
+
8
+ def initialize(*args)
9
+ end
10
+
11
+ def closed?
12
+ @closed ||= true
13
+ end
14
+
15
+ def readuntil(*args)
16
+ end
17
+
18
+ end
19
+
20
+ module StubResponse
21
+ def read_body(*args, &block)
22
+ yield @body if block_given?
23
+ @body
24
+ end
25
+ end
26
+
27
+ module Net #:nodoc: all
28
+
29
+ class BufferedIO
30
+ def initialize_with_webmock(io, debug_output = nil)
31
+ @read_timeout = 60
32
+ @rbuf = ''
33
+ @debug_output = debug_output
34
+
35
+ @io = case io
36
+ when Socket, OpenSSL::SSL::SSLSocket, IO
37
+ io
38
+ when String
39
+ if !io.include?("\0") && File.exists?(io) && !File.directory?(io)
40
+ File.open(io, "r")
41
+ else
42
+ StringIO.new(io)
43
+ end
44
+ end
45
+ raise "Unable to create local socket" unless @io
46
+ end
47
+ alias_method :initialize_without_webmock, :initialize
48
+ alias_method :initialize, :initialize_with_webmock
49
+ end
50
+
51
+ class HTTP
52
+ class << self
53
+ def socket_type_with_webmock
54
+ StubSocket
55
+ end
56
+ alias_method :socket_type_without_webmock, :socket_type
57
+ alias_method :socket_type, :socket_type_with_webmock
58
+ end
59
+
60
+ def request_with_webmock(request, body = nil, &block)
61
+ protocol = use_ssl? ? "https" : "http"
62
+
63
+ path = request.path
64
+ path = URI.parse(request.path).request_uri if request.path =~ /^http/
65
+
66
+ if request["authorization"] =~ /^Basic /
67
+ userinfo = WebMock::Utility.decode_userinfo_from_header(request["authorization"])
68
+ userinfo = WebMock::Utility.encode_unsafe_chars_in_userinfo(userinfo) + "@"
69
+ else
70
+ userinfo = ""
71
+ end
72
+
73
+ uri = "#{protocol}://#{userinfo}#{self.address}:#{self.port}#{path}"
74
+ method = request.method.downcase.to_sym
75
+
76
+ headers = Hash[*request.to_hash.map {|k,v| [k, v.flatten]}.flatten]
77
+ headers.reject! {|k,v| k =~ /[Aa]ccept/ && v = '*/*'}
78
+
79
+ request_profile = WebMock::RequestProfile.new(method, uri, body, headers)
80
+
81
+ if WebMock.registered_request?(request_profile)
82
+ @socket = Net::HTTP.socket_type.new
83
+ webmock_response = WebMock.response_for_request(request_profile)
84
+ build_net_http_response(webmock_response, &block)
85
+ elsif WebMock.net_connect_allowed?
86
+ WebMock::RequestRegistry.instance.requested.put(request_profile)
87
+ connect_without_webmock
88
+ request_without_webmock(request, body, &block)
89
+ else
90
+ uri = WebMock::Utility.strip_default_port_from_uri(uri)
91
+ message = "Real HTTP connections are disabled. Unregistered request: #{request.method} #{uri}"
92
+ message << " with body '#{body}'" if body
93
+ message << " with headers #{WebMock::Utility.normalize_headers(headers).inspect.gsub("\"","'")}" if
94
+ headers && !headers.empty?
95
+ raise WebMock::NetConnectNotAllowedError, message
96
+ end
97
+ end
98
+ alias_method :request_without_webmock, :request
99
+ alias_method :request, :request_with_webmock
100
+
101
+
102
+ def connect_with_webmock
103
+ unless @@alredy_checked_for_net_http_replacement_libs ||= false
104
+ WebMock::Utility.puts_warning_for_net_http_replacement_libs_if_needed
105
+ @@alredy_checked_for_net_http_replacement_libs = true
106
+ end
107
+ nil
108
+ end
109
+ alias_method :connect_without_webmock, :connect
110
+ alias_method :connect, :connect_with_webmock
111
+
112
+ def build_net_http_response(webmock_response, &block)
113
+ response = Net::HTTPResponse.send(:response_class, webmock_response.status.to_s).new("1.0", webmock_response.status.to_s, "")
114
+ response.instance_variable_set(:@body, webmock_response.body)
115
+ webmock_response.headers.to_a.each { |name, value| response[name] = value }
116
+
117
+ response.instance_variable_set(:@read, true)
118
+
119
+ response.extend StubResponse
120
+
121
+ webmock_response.raise_error_if_any
122
+
123
+ yield response if block_given?
124
+
125
+ response
126
+ end
127
+ end
128
+
129
+ end
@@ -0,0 +1,22 @@
1
+ module WebMock
2
+ class RequestExecutionVerifier
3
+
4
+ attr_accessor :request_profile, :expected_times_executed, :times_executed
5
+
6
+ def initialize(request_profile = nil, expected_times_executed = nil)
7
+ @request_profile = request_profile
8
+ @expected_times_executed = expected_times_executed || 1
9
+ end
10
+
11
+ def verify
12
+ @times_executed =
13
+ RequestRegistry.instance.times_executed(@request_profile)
14
+ @times_executed == @expected_times_executed
15
+ end
16
+
17
+ def failure_message
18
+ %Q(The request #{request_profile.to_s} was expected to execute #{expected_times_executed} time#{ (expected_times_executed == 1) ? '' : 's'} but it executed #{times_executed} time#{ (times_executed == 1) ? '' : 's'})
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,67 @@
1
+ module WebMock
2
+
3
+ class RequestProfile < Struct.new(:method, :uri, :body, :headers)
4
+
5
+ def initialize(method, uri, body = nil, headers = nil)
6
+ super
7
+ self.uri = WebMock::URL.normalize_uri(self.uri) unless self.uri.is_a?(URI)
8
+ self.headers = Utility.normalize_headers(self.headers)
9
+ end
10
+
11
+ def with(options)
12
+ self.body = options[:body] if options.has_key?(:body)
13
+ self.headers = Utility.normalize_headers(options[:headers]) if options.has_key?(:headers)
14
+ self
15
+ end
16
+
17
+ #self needs to be a subset of other. Other needs to be more general.
18
+ def match(other)
19
+ match_method(other) &&
20
+ match_body(other) &&
21
+ match_headers(other) &&
22
+ match_url(other)
23
+ end
24
+
25
+ def to_s
26
+ string = "#{self.method.to_s.upcase} #{self.uri}"
27
+ string << " with body '#{body}'" if body
28
+ if headers && !headers.empty?
29
+ string << " with headers #{WebMock::Utility.normalize_headers(headers).inspect.gsub("\"","'")}"
30
+ end
31
+ string
32
+ end
33
+
34
+ private
35
+
36
+ def match_url(other)
37
+ raise "Can't match regexp request profile" if self.uri.is_a?(Regexp)
38
+ @uris_to_check ||= WebMock::URL.variations_of_uri_as_strings(self.uri)
39
+ if other.uri.is_a?(URI)
40
+ @uris_to_check.include?(other.uri.to_s)
41
+ elsif other.uri.is_a?(Regexp)
42
+ @uris_to_check.any? { |u| u.match(other.uri) }
43
+ else
44
+ false
45
+ end
46
+ end
47
+
48
+ def match_headers(other)
49
+ return false if self.headers && !self.headers.empty? && other.headers && other.headers.empty?
50
+ if other.headers && !other.headers.empty?
51
+ other.headers.each do | key, value |
52
+ return false unless (self.headers && self.headers.has_key?(key) && value == self.headers[key])
53
+ end
54
+ end
55
+ return true
56
+ end
57
+
58
+ def match_body(other)
59
+ other.body == self.body || other.body.nil?
60
+ end
61
+
62
+ def match_method(other)
63
+ other.method == self.method || other.method == :any
64
+ end
65
+ end
66
+
67
+ end