vcr 0.3.1 → 0.4.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 (70) hide show
  1. data/CHANGELOG.md +62 -0
  2. data/README.md +224 -0
  3. data/Rakefile +12 -5
  4. data/VERSION +1 -1
  5. data/benchmarks/http_stubbing_libraries.rb +59 -0
  6. data/features/fixtures/vcr_cassettes/1.8.6/cucumber_tags/replay_cassette1.yml +25 -25
  7. data/features/fixtures/vcr_cassettes/1.8.6/cucumber_tags/replay_cassette2.yml +32 -30
  8. data/features/fixtures/vcr_cassettes/1.8.6/cucumber_tags/replay_cassette3.yml +40 -40
  9. data/features/fixtures/vcr_cassettes/1.8.6/nested_replay_cassette.yml +16 -15
  10. data/features/fixtures/vcr_cassettes/1.8.6/not_the_real_response.yml +25 -25
  11. data/features/fixtures/vcr_cassettes/1.8.7/cucumber_tags/replay_cassette1.yml +23 -23
  12. data/features/fixtures/vcr_cassettes/1.8.7/cucumber_tags/replay_cassette2.yml +24 -22
  13. data/features/fixtures/vcr_cassettes/1.8.7/cucumber_tags/replay_cassette3.yml +36 -36
  14. data/features/fixtures/vcr_cassettes/1.8.7/nested_replay_cassette.yml +12 -11
  15. data/features/fixtures/vcr_cassettes/1.8.7/not_the_real_response.yml +23 -23
  16. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette1.yml +24 -24
  17. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette2.yml +26 -24
  18. data/features/fixtures/vcr_cassettes/1.9.1/cucumber_tags/replay_cassette3.yml +38 -38
  19. data/features/fixtures/vcr_cassettes/1.9.1/nested_replay_cassette.yml +13 -12
  20. data/features/fixtures/vcr_cassettes/1.9.1/not_the_real_response.yml +24 -24
  21. data/features/record_response.feature +2 -2
  22. data/features/replay_recorded_response.feature +1 -1
  23. data/features/step_definitions/vcr_steps.rb +8 -8
  24. data/features/support/env.rb +6 -0
  25. data/lib/vcr.rb +16 -3
  26. data/lib/vcr/cassette.rb +49 -46
  27. data/lib/vcr/config.rb +8 -0
  28. data/lib/vcr/extensions/fake_web.rb +12 -26
  29. data/lib/vcr/extensions/net_http.rb +9 -26
  30. data/lib/vcr/http_stubbing_adapters/base.rb +34 -0
  31. data/lib/vcr/http_stubbing_adapters/fakeweb.rb +75 -0
  32. data/lib/vcr/http_stubbing_adapters/webmock.rb +80 -0
  33. data/lib/vcr/structs.rb +44 -0
  34. data/lib/vcr/task_runner.rb +47 -0
  35. data/lib/vcr/tasks/vcr.rake +9 -0
  36. data/spec/cassette_spec.rb +70 -71
  37. data/spec/config_spec.rb +27 -0
  38. data/spec/extensions/net_http_spec.rb +21 -17
  39. data/spec/fixtures/1.8.6/0_3_1_cassette.yml +29 -0
  40. data/spec/fixtures/1.8.6/cassette_spec/example.yml +110 -108
  41. data/spec/fixtures/1.8.6/example_net_http.yml +14 -0
  42. data/spec/fixtures/1.8.6/example_net_http_request.yml +12 -0
  43. data/spec/fixtures/1.8.6/example_net_http_response.yml +25 -0
  44. data/spec/fixtures/1.8.6/fake_example.com_responses.yml +90 -0
  45. data/spec/fixtures/1.8.7/0_3_1_cassette.yml +29 -0
  46. data/spec/fixtures/1.8.7/cassette_spec/example.yml +110 -108
  47. data/spec/fixtures/1.8.7/example_net_http.yml +14 -0
  48. data/spec/fixtures/1.8.7/example_net_http_request.yml +12 -0
  49. data/spec/fixtures/1.8.7/example_net_http_response.yml +25 -0
  50. data/spec/fixtures/1.8.7/fake_example.com_responses.yml +90 -0
  51. data/spec/fixtures/1.9.1/0_3_1_cassette.yml +29 -0
  52. data/spec/fixtures/1.9.1/cassette_spec/example.yml +62 -59
  53. data/spec/fixtures/1.9.1/example_net_http.yml +14 -0
  54. data/spec/fixtures/1.9.1/example_net_http_request.yml +12 -0
  55. data/spec/fixtures/1.9.1/example_net_http_response.yml +25 -0
  56. data/spec/fixtures/1.9.1/fake_example.com_responses.yml +90 -0
  57. data/spec/http_stubbing_adapters/fakeweb_spec.rb +24 -0
  58. data/spec/http_stubbing_adapters/webmock_spec.rb +23 -0
  59. data/spec/spec_helper.rb +5 -0
  60. data/spec/structs_spec.rb +95 -0
  61. data/spec/support/http_stubbing_adapter.rb +113 -0
  62. data/spec/task_runner_spec.rb +59 -0
  63. data/spec/vcr_spec.rb +37 -0
  64. data/vcr.gemspec +45 -15
  65. metadata +67 -26
  66. data/History.rdoc +0 -31
  67. data/README.rdoc +0 -222
  68. data/lib/vcr/recorded_response.rb +0 -4
  69. data/spec/extensions/fake_web_spec.rb +0 -63
  70. data/spec/recorded_response_spec.rb +0 -25
@@ -13,6 +13,12 @@ require 'spec/expectations'
13
13
 
14
14
  VCR.config do |c|
15
15
  c.cassette_library_dir = File.join(File.dirname(__FILE__), '..', 'fixtures', 'vcr_cassettes', RUBY_VERSION)
16
+ c.http_stubbing_library = if ENV['HTTP_STUBBING_ADAPTER'].to_s == ''
17
+ warn "Using fakeweb for VCR's cucumber features since the adapter was not specified. Set HTTP_STUBBING_ADAPTER to specify."
18
+ :fakeweb
19
+ else
20
+ ENV['HTTP_STUBBING_ADAPTER'].to_sym
21
+ end
16
22
  end
17
23
 
18
24
  VCR.module_eval do
data/lib/vcr.rb CHANGED
@@ -2,12 +2,12 @@ require 'vcr/cassette'
2
2
  require 'vcr/config'
3
3
  require 'vcr/cucumber_tags'
4
4
  require 'vcr/deprecations'
5
- require 'vcr/recorded_response'
5
+ require 'vcr/structs'
6
6
 
7
- require 'vcr/extensions/fake_web'
8
- require 'vcr/extensions/net_http'
9
7
  require 'vcr/extensions/net_read_adapter'
10
8
 
9
+ require 'vcr/http_stubbing_adapters/base'
10
+
11
11
  module VCR
12
12
  extend self
13
13
 
@@ -36,6 +36,8 @@ module VCR
36
36
 
37
37
  def config
38
38
  yield VCR::Config
39
+ http_stubbing_adapter.check_version!
40
+ http_stubbing_adapter.http_connections_allowed = false
39
41
  end
40
42
 
41
43
  def cucumber_tags(&block)
@@ -43,6 +45,17 @@ module VCR
43
45
  yield VCR::CucumberTags.new(main_object)
44
46
  end
45
47
 
48
+ def http_stubbing_adapter
49
+ @http_stubbing_adapter ||= case VCR::Config.http_stubbing_library
50
+ when :fakeweb
51
+ VCR::HttpStubbingAdapters::FakeWeb
52
+ when :webmock
53
+ VCR::HttpStubbingAdapters::WebMock
54
+ else
55
+ raise ArgumentError.new("The http stubbing library is not configured correctly. You should set it to :webmock or :fakeweb.")
56
+ end
57
+ end
58
+
46
59
  private
47
60
 
48
61
  def cassettes
@@ -10,92 +10,95 @@ module VCR
10
10
  def initialize(name, options = {})
11
11
  @name = name
12
12
  @record_mode = options[:record] || VCR::Config.default_cassette_options[:record]
13
- deprecate_unregistered_record_mode
14
13
  @allow_real_http_lambda = allow_real_http_lambda_for(options[:allow_real_http] || VCR::Config.default_cassette_options[:allow_real_http])
15
- self.class.raise_error_unless_valid_record_mode(record_mode)
16
- set_fakeweb_allow_net_connect
17
- load_recorded_responses
14
+
15
+ deprecate_unregistered_record_mode
16
+ raise_error_unless_valid_record_mode(record_mode)
17
+
18
+ set_http_connections_allowed
19
+ load_recorded_interactions
18
20
  end
19
21
 
20
22
  def eject
21
- write_recorded_responses_to_disk
22
- deregister_original_recorded_responses
23
- restore_fakeweb_allow_net_conect
23
+ write_recorded_interactions_to_disk
24
+ VCR.http_stubbing_adapter.restore_stubs_checkpoint(name)
25
+ restore_http_connections_allowed
24
26
  end
25
27
 
26
- def recorded_responses
27
- @recorded_responses ||= []
28
+ def recorded_interactions
29
+ @recorded_interactions ||= []
28
30
  end
29
31
 
30
- def store_recorded_response!(recorded_response)
31
- recorded_responses << recorded_response
32
+ def record_http_interaction(interaction)
33
+ recorded_interactions << interaction
32
34
  end
33
35
 
34
36
  def file
35
37
  File.join(VCR::Config.cassette_library_dir, "#{name.to_s.gsub(/[^\w\-\/]+/, '_')}.yml") if VCR::Config.cassette_library_dir
36
38
  end
37
39
 
38
- def self.raise_error_unless_valid_record_mode(record_mode)
40
+ def allow_real_http_requests_to?(uri)
41
+ @allow_real_http_lambda ? @allow_real_http_lambda.call(uri) : false
42
+ end
43
+
44
+ private
45
+
46
+ def raise_error_unless_valid_record_mode(record_mode)
39
47
  unless VALID_RECORD_MODES.include?(record_mode)
40
48
  raise ArgumentError.new("#{record_mode} is not a valid cassette record mode. Valid options are: #{VALID_RECORD_MODES.inspect}")
41
49
  end
42
50
  end
43
51
 
44
- def allow_real_http_requests_to?(uri)
45
- @allow_real_http_lambda ? @allow_real_http_lambda.call(uri) : false
52
+ def new_recorded_interactions
53
+ recorded_interactions - @original_recorded_interactions
46
54
  end
47
55
 
48
- def new_recorded_responses
49
- recorded_responses - @original_recorded_responses
50
- end
51
-
52
- def should_allow_net_connect?
56
+ def should_allow_http_connections?
53
57
  [:new_episodes, :all].include?(record_mode)
54
58
  end
55
59
 
56
- def set_fakeweb_allow_net_connect
57
- @orig_fakeweb_allow_connect = FakeWeb.allow_net_connect?
58
- FakeWeb.allow_net_connect = should_allow_net_connect?
60
+ def set_http_connections_allowed
61
+ @orig_http_connections_allowed = VCR.http_stubbing_adapter.http_connections_allowed?
62
+ VCR.http_stubbing_adapter.http_connections_allowed = should_allow_http_connections?
59
63
  end
60
64
 
61
- def restore_fakeweb_allow_net_conect
62
- FakeWeb.allow_net_connect = @orig_fakeweb_allow_connect
65
+ def restore_http_connections_allowed
66
+ VCR.http_stubbing_adapter.http_connections_allowed = @orig_http_connections_allowed
63
67
  end
64
68
 
65
- def load_recorded_responses
66
- @original_recorded_responses = []
69
+ def load_recorded_interactions
70
+ VCR.http_stubbing_adapter.create_stubs_checkpoint(name)
71
+ @original_recorded_interactions = []
67
72
  return if record_mode == :all
68
73
 
69
74
  if file
70
- @original_recorded_responses = File.open(file, 'r') { |f| YAML.load(f.read) } if File.exist?(file)
71
- recorded_responses.replace(@original_recorded_responses)
75
+ @original_recorded_interactions = begin
76
+ yaml_content = File.read(file)
77
+ YAML.load(yaml_content)
78
+ rescue TypeError
79
+ if yaml_content =~ /VCR::RecordedResponse/
80
+ raise "The VCR cassette #{name} uses an old format that is now deprecated. VCR provides a rake task to migrate your old cassettes to the new format. See http://github.com/myronmarston/vcr/blob/master/CHANGELOG.md for more info."
81
+ else
82
+ raise
83
+ end
84
+ end if File.exist?(file)
85
+
86
+ recorded_interactions.replace(@original_recorded_interactions)
72
87
  end
73
88
 
74
- register_responses_with_fakeweb
89
+ VCR.http_stubbing_adapter.stub_requests(recorded_interactions)
75
90
  end
76
91
 
77
- def register_responses_with_fakeweb
78
- requests = Hash.new([])
79
- recorded_responses.each do |rr|
80
- requests[[rr.method, rr.uri]] += [rr.response]
81
- end
82
- requests.each do |request, responses|
83
- FakeWeb.register_uri(request.first, request.last, responses.map{ |r| { :response => r } })
84
- end
85
- end
86
-
87
- def write_recorded_responses_to_disk
88
- if VCR::Config.cassette_library_dir && new_recorded_responses.size > 0
92
+ def write_recorded_interactions_to_disk
93
+ if VCR::Config.cassette_library_dir && new_recorded_interactions.size > 0
89
94
  directory = File.dirname(file)
90
95
  FileUtils.mkdir_p directory unless File.exist?(directory)
91
- File.open(file, 'w') { |f| f.write recorded_responses.to_yaml }
96
+ File.open(file, 'w') { |f| f.write recorded_interactions.to_yaml }
92
97
  end
93
98
  end
94
99
 
95
- def deregister_original_recorded_responses
96
- @original_recorded_responses.each do |rr|
97
- FakeWeb.remove_from_registry(rr.method, rr.uri)
98
- end
100
+ def unstub_requests
101
+ VCR.http_stubbing_adapter.unstub_requests(@original_recorded_interactions)
99
102
  end
100
103
 
101
104
  def allow_real_http_lambda_for(allow_option)
@@ -13,6 +13,14 @@ module VCR
13
13
  def default_cassette_options
14
14
  @default_cassette_options ||= {}
15
15
  end
16
+
17
+ attr_writer :http_stubbing_library
18
+ def http_stubbing_library
19
+ @http_stubbing_library ||= begin
20
+ defined_constants = [:FakeWeb, :WebMock].select { |c| Object.const_defined?(c) }
21
+ defined_constants[0].to_s.downcase.to_sym if defined_constants.size == 1
22
+ end
23
+ end
16
24
  end
17
25
  end
18
26
  end
@@ -1,34 +1,20 @@
1
- require 'fake_web'
1
+ require 'fakeweb'
2
2
 
3
3
  module FakeWeb
4
- def self.remove_from_registry(method, url)
5
- Registry.instance.remove(method, url)
6
- end
4
+ def self.request_uri(net_http, request)
5
+ # Copied from: http://github.com/chrisk/fakeweb/blob/fakeweb-1.2.8/lib/fake_web/ext/net_http.rb#L39-52
6
+ protocol = net_http.use_ssl? ? "https" : "http"
7
7
 
8
- def self.with_allow_net_connect_set_to(value)
9
- original_value = FakeWeb.allow_net_connect?
10
- begin
11
- FakeWeb.allow_net_connect = value
12
- yield
13
- ensure
14
- FakeWeb.allow_net_connect = original_value
15
- end
16
- end
8
+ path = request.path
9
+ path = URI.parse(request.path).request_uri if request.path =~ /^http/
17
10
 
18
- class Registry #:nodoc:
19
- def remove(method, url)
20
- uri_map.delete_if do |uri, method_hash|
21
- if normalize_uri(uri) == normalize_uri(url)
22
- method_hash.delete(method)
23
- method_hash.empty? # there's no point in keeping this entry in the uri map if its method hash is empty...
24
- end
25
- end
11
+ if request["authorization"] =~ /^Basic /
12
+ userinfo = FakeWeb::Utility.decode_userinfo_from_header(request["authorization"])
13
+ userinfo = FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) + "@"
14
+ else
15
+ userinfo = ""
26
16
  end
27
- end
28
17
 
29
- class NetConnectNotAllowedError
30
- def message
31
- super + '. You can use VCR to automatically record this request and replay it later with fakeweb. For more details, see the VCR README at: http://github.com/myronmarston/vcr'
32
- end
18
+ "#{protocol}://#{userinfo}#{net_http.address}:#{net_http.port}#{path}"
33
19
  end
34
20
  end
@@ -3,48 +3,31 @@ require 'net/http'
3
3
  module Net
4
4
  class HTTP
5
5
  def request_with_vcr(request, body = nil, &block)
6
- @__request_with_vcr_call_count = (@__request_with_vcr_call_count || 0) + 1
7
- uri = URI.parse(__vcr_uri__(request))
6
+ uri = URI.parse(VCR.http_stubbing_adapter.request_uri(self, request))
7
+
8
8
  if (cassette = VCR.current_cassette) && cassette.allow_real_http_requests_to?(uri)
9
- FakeWeb.with_allow_net_connect_set_to(true) { request_without_vcr(request, body, &block) }
9
+ VCR.http_stubbing_adapter.with_http_connections_allowed_set_to(true) do
10
+ request_without_vcr(request, body, &block)
11
+ end
10
12
  else
11
13
  response = request_without_vcr(request, body)
12
- __store_response_with_vcr__(response, request) if @__request_with_vcr_call_count == 1
14
+ __store_response_with_vcr__(response, request) if started?
13
15
  yield response if block_given?
14
16
  response
15
17
  end
16
- ensure
17
- @__request_with_vcr_call_count -= 1
18
18
  end
19
19
  alias_method :request_without_vcr, :request
20
20
  alias_method :request, :request_with_vcr
21
21
 
22
22
  private
23
23
 
24
- def __vcr_uri__(request)
25
- # Copied from: http://github.com/chrisk/fakeweb/blob/fakeweb-1.2.8/lib/fake_web/ext/net_http.rb#L39-52
26
- protocol = use_ssl? ? "https" : "http"
27
-
28
- path = request.path
29
- path = URI.parse(request.path).request_uri if request.path =~ /^http/
30
-
31
- if request["authorization"] =~ /^Basic /
32
- userinfo = FakeWeb::Utility.decode_userinfo_from_header(request["authorization"])
33
- userinfo = FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) + "@"
34
- else
35
- userinfo = ""
36
- end
37
-
38
- "#{protocol}://#{userinfo}#{self.address}:#{self.port}#{path}"
39
- end
40
-
41
24
  def __store_response_with_vcr__(response, request)
42
25
  if cassette = VCR.current_cassette
43
- uri = __vcr_uri__(request)
26
+ uri = VCR.http_stubbing_adapter.request_uri(self, request)
44
27
  method = request.method.downcase.to_sym
45
28
 
46
- unless FakeWeb.registered_uri?(method, uri)
47
- cassette.store_recorded_response!(VCR::RecordedResponse.new(method, uri, response))
29
+ unless VCR.http_stubbing_adapter.request_stubbed?(method, uri)
30
+ cassette.record_http_interaction(VCR::HTTPInteraction.from_net_http_objects(self, request, response))
48
31
  end
49
32
  end
50
33
  end
@@ -0,0 +1,34 @@
1
+ module VCR
2
+ module HttpStubbingAdapters
3
+ autoload :FakeWeb, 'vcr/http_stubbing_adapters/fakeweb'
4
+ autoload :WebMock, 'vcr/http_stubbing_adapters/webmock'
5
+
6
+ class Base
7
+ class << self
8
+ def with_http_connections_allowed_set_to(value)
9
+ original_value = http_connections_allowed?
10
+ self.http_connections_allowed = value
11
+ begin
12
+ yield
13
+ ensure
14
+ self.http_connections_allowed = original_value
15
+ end
16
+ end
17
+
18
+ def meets_version_requirement?(version, required_version)
19
+ major, minor, patch = *version.split('.').map { |v| v.to_i }
20
+ req_major, req_minor, req_patch = *required_version.split('.').map { |v| v.to_i }
21
+
22
+ return false if major < req_major
23
+ return true if major > req_major
24
+
25
+ return false if minor < req_minor
26
+ return true if minor > req_minor
27
+
28
+ patch >= req_patch
29
+ end
30
+
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,75 @@
1
+ require 'vcr/extensions/fake_web'
2
+ require 'vcr/extensions/net_http'
3
+
4
+ module VCR
5
+ module HttpStubbingAdapters
6
+ class FakeWeb < Base
7
+ class << self
8
+ def check_version!
9
+ unless meets_version_requirement?(::FakeWeb::VERSION, '1.2.8')
10
+ raise "You are using FakeWeb #{::FakeWeb::VERSION}. VCR requires version 1.2.8 or greater."
11
+ end
12
+ end
13
+
14
+ def http_connections_allowed?
15
+ ::FakeWeb.allow_net_connect?
16
+ end
17
+
18
+ def http_connections_allowed=(value)
19
+ ::FakeWeb.allow_net_connect = value
20
+ end
21
+
22
+ def stub_requests(http_interactions)
23
+ requests = Hash.new([])
24
+
25
+ http_interactions.each do |i|
26
+ requests[[i.request.method, i.request.uri]] += [i.response]
27
+ end
28
+
29
+ requests.each do |request, responses|
30
+ ::FakeWeb.register_uri(request.first, request.last, responses.map{ |r| response_hash(r) })
31
+ end
32
+ end
33
+
34
+ def create_stubs_checkpoint(checkpoint_name)
35
+ checkpoints[checkpoint_name] = ::FakeWeb::Registry.instance.uri_map.dup
36
+ end
37
+
38
+ def restore_stubs_checkpoint(checkpoint_name)
39
+ ::FakeWeb::Registry.instance.uri_map = checkpoints.delete(checkpoint_name)
40
+ end
41
+
42
+ def request_stubbed?(method, uri)
43
+ ::FakeWeb.registered_uri?(method, uri)
44
+ end
45
+
46
+ def request_uri(net_http, request)
47
+ ::FakeWeb.request_uri(net_http, request)
48
+ end
49
+
50
+ private
51
+
52
+ def checkpoints
53
+ @checkpoints ||= {}
54
+ end
55
+
56
+ def response_hash(response)
57
+ response.headers.merge(
58
+ :body => response.body,
59
+ :status => [response.status.code.to_s, response.status.message]
60
+ )
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ if defined?(FakeWeb::NetConnectNotAllowedError)
68
+ module FakeWeb
69
+ class NetConnectNotAllowedError
70
+ def message
71
+ super + '. You can use VCR to automatically record this request and replay it later. For more details, see the VCR README at: http://github.com/myronmarston/vcr'
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,80 @@
1
+ require 'webmock'
2
+ require 'vcr/extensions/net_http'
3
+
4
+ module VCR
5
+ module HttpStubbingAdapters
6
+ class WebMock < Base
7
+ class << self
8
+ VERSION_REQUIREMENT = '1.1.0'
9
+
10
+ def check_version!
11
+ unless meets_version_requirement?(::WebMock.version, VERSION_REQUIREMENT)
12
+ raise "You are using WebMock #{::WebMock.version}. VCR requires version #{VERSION_REQUIREMENT} or greater."
13
+ end
14
+ end
15
+
16
+ def http_connections_allowed?
17
+ ::WebMock::Config.instance.allow_net_connect
18
+ end
19
+
20
+ def http_connections_allowed=(value)
21
+ ::WebMock::Config.instance.allow_net_connect = value
22
+ end
23
+
24
+ def stub_requests(recorded_responses)
25
+ requests = Hash.new([])
26
+
27
+ # TODO: use the entire request signature, but make it configurable.
28
+ recorded_responses.each do |rr|
29
+ requests[[rr.method, rr.uri]] += [rr.response]
30
+ end
31
+
32
+ requests.each do |request, responses|
33
+ ::WebMock.stub_request(request.first, request.last).
34
+ to_return(responses.map{ |r| response_hash(r) })
35
+ end
36
+ end
37
+
38
+ def create_stubs_checkpoint(checkpoint_name)
39
+ checkpoints[checkpoint_name] = ::WebMock::RequestRegistry.instance.request_stubs.dup
40
+ end
41
+
42
+ def restore_stubs_checkpoint(checkpoint_name)
43
+ ::WebMock::RequestRegistry.instance.request_stubs = checkpoints.delete(checkpoint_name)
44
+ end
45
+
46
+ def request_stubbed?(method, uri)
47
+ !!::WebMock.registered_request?(::WebMock::RequestSignature.new(method, uri))
48
+ end
49
+
50
+ def request_uri(net_http, request)
51
+ ::WebMock::NetHTTPUtility.request_signature_from_request(net_http, request).uri.to_s
52
+ end
53
+
54
+ private
55
+
56
+ def response_hash(response)
57
+ {
58
+ :body => response.body,
59
+ :status => [response.status.code.to_i, response.status.message],
60
+ :headers => response.headers
61
+ }
62
+ end
63
+
64
+ def checkpoints
65
+ @checkpoints ||= {}
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ if defined?(WebMock::NetConnectNotAllowedError)
73
+ module WebMock
74
+ class NetConnectNotAllowedError
75
+ def message
76
+ super + '. You can use VCR to automatically record this request and replay it later. For more details, see the VCR README at: http://github.com/myronmarston/vcr'
77
+ end
78
+ end
79
+ end
80
+ end