vcr 2.0.0.beta2 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +0 -2
  3. data/CHANGELOG.md +22 -1
  4. data/CONTRIBUTING.md +46 -0
  5. data/Gemfile +1 -9
  6. data/README.md +8 -2
  7. data/Rakefile +12 -1
  8. data/cucumber.yml +8 -9
  9. data/features/.nav +10 -4
  10. data/features/cassettes/format.feature +1 -1
  11. data/features/cassettes/no_cassette.feature +8 -11
  12. data/features/configuration/allow_http_connections_when_no_cassette.feature +4 -4
  13. data/features/configuration/filter_sensitive_data.feature +3 -0
  14. data/features/configuration/hook_into.feature +4 -8
  15. data/features/configuration/ignore_request.feature +191 -0
  16. data/features/getting_started.md +38 -21
  17. data/features/hooks/after_http_request.feature +44 -0
  18. data/features/hooks/around_http_request.feature +56 -0
  19. data/features/hooks/before_http_request.feature +44 -0
  20. data/features/hooks/before_playback.feature +181 -0
  21. data/features/hooks/before_record.feature +172 -0
  22. data/features/middleware/faraday.feature +7 -3
  23. data/features/record_modes/none.feature +2 -1
  24. data/features/record_modes/once.feature +2 -1
  25. data/features/request_matching/body.feature +2 -2
  26. data/features/request_matching/custom_matcher.feature +2 -2
  27. data/features/request_matching/headers.feature +2 -2
  28. data/features/request_matching/host.feature +2 -2
  29. data/features/request_matching/identical_request_sequence.feature +2 -2
  30. data/features/request_matching/method.feature +2 -2
  31. data/features/request_matching/path.feature +2 -2
  32. data/features/request_matching/playback_repeats.feature +2 -1
  33. data/features/request_matching/uri.feature +2 -2
  34. data/features/support/env.rb +21 -12
  35. data/features/test_frameworks/cucumber.feature +9 -4
  36. data/features/test_frameworks/{rspec.feature → rspec_macro.feature} +7 -7
  37. data/features/test_frameworks/rspec_metadata.feature +90 -0
  38. data/lib/vcr.rb +1 -1
  39. data/lib/vcr/cassette.rb +3 -3
  40. data/lib/vcr/cassette/http_interaction_list.rb +13 -9
  41. data/lib/vcr/cassette/migrator.rb +1 -1
  42. data/lib/vcr/configuration.rb +37 -0
  43. data/lib/vcr/errors.rb +172 -6
  44. data/lib/vcr/library_hooks.rb +4 -6
  45. data/lib/vcr/library_hooks/excon.rb +23 -11
  46. data/lib/vcr/library_hooks/fakeweb.rb +85 -24
  47. data/lib/vcr/library_hooks/faraday.rb +30 -2
  48. data/lib/vcr/library_hooks/typhoeus.rb +25 -3
  49. data/lib/vcr/library_hooks/webmock.rb +25 -36
  50. data/lib/vcr/middleware/faraday.rb +23 -5
  51. data/lib/vcr/request_handler.rb +12 -1
  52. data/lib/vcr/request_ignorer.rb +12 -1
  53. data/lib/vcr/request_matcher_registry.rb +1 -9
  54. data/lib/vcr/structs.rb +32 -2
  55. data/lib/vcr/test_frameworks/rspec.rb +28 -0
  56. data/lib/vcr/util/hooks.rb +12 -4
  57. data/lib/vcr/util/version_checker.rb +2 -0
  58. data/lib/vcr/version.rb +1 -1
  59. data/spec/fixtures/cassette_spec/example.yml +1 -1
  60. data/spec/fixtures/{fake_example.com_responses.yml → fake_example_responses.yml} +0 -0
  61. data/spec/monkey_patches.rb +1 -1
  62. data/spec/spec_helper.rb +3 -1
  63. data/spec/support/http_library_adapters.rb +4 -3
  64. data/spec/support/shared_example_groups/hook_into_http_library.rb +194 -12
  65. data/spec/support/shared_example_groups/request_hooks.rb +58 -0
  66. data/spec/support/shared_example_groups/version_checking.rb +5 -0
  67. data/spec/support/sinatra_app.rb +17 -9
  68. data/spec/support/vcr_stub_helpers.rb +17 -0
  69. data/spec/vcr/cassette/http_interaction_list_spec.rb +28 -29
  70. data/spec/vcr/cassette/migrator_spec.rb +6 -7
  71. data/spec/vcr/cassette_spec.rb +5 -5
  72. data/spec/vcr/configuration_spec.rb +51 -32
  73. data/spec/vcr/deprecations_spec.rb +0 -8
  74. data/spec/vcr/errors_spec.rb +129 -0
  75. data/spec/vcr/library_hooks/excon_spec.rb +21 -4
  76. data/spec/vcr/library_hooks/fakeweb_spec.rb +71 -3
  77. data/spec/vcr/library_hooks/faraday_spec.rb +45 -0
  78. data/spec/vcr/library_hooks/typhoeus_spec.rb +31 -1
  79. data/spec/vcr/library_hooks/webmock_spec.rb +26 -3
  80. data/spec/vcr/middleware/faraday_spec.rb +84 -1
  81. data/spec/vcr/request_ignorer_spec.rb +16 -0
  82. data/spec/vcr/request_matcher_registry_spec.rb +0 -26
  83. data/spec/vcr/structs_spec.rb +61 -1
  84. data/spec/vcr/test_frameworks/rspec_spec.rb +32 -0
  85. data/spec/vcr/util/hooks_spec.rb +73 -63
  86. data/spec/vcr_spec.rb +2 -2
  87. data/vcr.gemspec +5 -5
  88. metadata +51 -31
  89. data/features/configuration/hooks.feature +0 -270
  90. data/features/configuration/ignore_hosts.feature +0 -61
  91. data/features/configuration/ignore_localhost.feature +0 -97
@@ -42,7 +42,7 @@ module VCR
42
42
 
43
43
  hash = {
44
44
  "http_interactions" => http_interactions,
45
- "recorded_with" => "VCR 1.11.3" # assume the last 1.x release
45
+ "recorded_with" => "VCR #{VCR.version}"
46
46
  }
47
47
 
48
48
  def hash.each
@@ -9,6 +9,8 @@ module VCR
9
9
  define_hook :before_record
10
10
  define_hook :before_playback
11
11
  define_hook :after_library_hooks_loaded
12
+ define_hook :before_http_request
13
+ define_hook :after_http_request, :prepend
12
14
 
13
15
  def initialize
14
16
  @allow_http_connections_when_no_cassette = nil
@@ -48,6 +50,10 @@ module VCR
48
50
  VCR.request_ignorer.ignore_localhost = value
49
51
  end
50
52
 
53
+ def ignore_request(&block)
54
+ VCR.request_ignorer.ignore_request(&block)
55
+ end
56
+
51
57
  attr_writer :allow_http_connections_when_no_cassette
52
58
  def allow_http_connections_when_no_cassette?
53
59
  !!@allow_http_connections_when_no_cassette
@@ -62,11 +68,28 @@ module VCR
62
68
  interaction.filter!(placeholder, call_block(block, interaction))
63
69
  end
64
70
  end
71
+ alias define_cassette_placeholder filter_sensitive_data
65
72
 
66
73
  def cassette_serializers
67
74
  VCR.cassette_serializers
68
75
  end
69
76
 
77
+ def around_http_request(&block)
78
+ require 'fiber'
79
+ rescue LoadError
80
+ raise Errors::NotSupportedError.new \
81
+ "VCR::Configuration#around_http_request requires fibers, " +
82
+ "which are not available on your ruby intepreter."
83
+ else
84
+ fiber, hook_decaration = nil, caller.first
85
+ before_http_request { |request| fiber = start_new_fiber_for(request, block) }
86
+ after_http_request { |request| resume_fiber(fiber, hook_decaration) }
87
+ end
88
+
89
+ def configure_rspec_metadata!
90
+ VCR::RSpec::Metadata.configure!
91
+ end
92
+
70
93
  private
71
94
 
72
95
  def load_library_hook(hook)
@@ -76,6 +99,20 @@ module VCR
76
99
  raise e unless e.message.include?(file) # in case FakeWeb/WebMock/etc itself is not available
77
100
  raise ArgumentError.new("#{hook.inspect} is not a supported VCR HTTP library hook.")
78
101
  end
102
+
103
+ def resume_fiber(fiber, hook_declaration)
104
+ fiber.resume
105
+ rescue FiberError
106
+ raise Errors::AroundHTTPRequestHookError.new \
107
+ "Your around_http_request hook declared at #{hook_declaration}" +
108
+ " must call #proceed on the yielded request but did not."
109
+ end
110
+
111
+ def start_new_fiber_for(request, block)
112
+ Fiber.new(&block).tap do |fiber|
113
+ fiber.resume(request.fiber_aware)
114
+ end
115
+ end
79
116
  end
80
117
  end
81
118
 
data/lib/vcr/errors.rb CHANGED
@@ -7,15 +7,181 @@ module VCR
7
7
  class LibraryVersionTooLowError < Error; end
8
8
  class UnregisteredMatcherError < Error; end
9
9
  class InvalidCassetteFormatError < Error; end
10
+ class AroundHTTPRequestHookError < Error; end
11
+ class NotSupportedError < Error; end
12
+
13
+ class UnhandledHTTPRequestError < Error
14
+ attr_reader :request
10
15
 
11
- class HTTPConnectionNotAllowedError < Error
12
16
  def initialize(request)
13
- super \
14
- "Real HTTP connections are disabled. " +
15
- "Request: #{request.method.to_s.upcase} #{request.uri}. " +
16
- "You can use VCR to automatically record this request and replay it later. " +
17
- "For more details, visit the VCR documentation at: http://relishapp.com/myronmarston/vcr/v/#{VCR.version.gsub('.', '-')}"
17
+ @request = request
18
+ super construct_message
19
+ end
20
+
21
+ private
22
+
23
+ def relish_version_slug
24
+ @relish_version_slug ||= VCR.version.gsub(/\W/, '-')
25
+ end
26
+
27
+ def construct_message
28
+ ["", "", "=" * 80,
29
+ "An HTTP request has been made that VCR does not know how to handle:",
30
+ " #{request_description}\n",
31
+ cassette_description,
32
+ formatted_suggestions,
33
+ "=" * 80, "", ""].join("\n")
34
+ end
35
+
36
+ def request_description
37
+ "#{request.method.to_s.upcase} #{request.uri}"
38
+ end
39
+
40
+ def cassette_description
41
+ if cassette = VCR.current_cassette
42
+ ["VCR is currently using the following cassette:",
43
+ " - #{cassette.file}",
44
+ " - :record => #{cassette.record_mode.inspect}",
45
+ " - :match_requests_on => #{cassette.match_requests_on.inspect}\n",
46
+ "Under the current configuration VCR can not find a suitable HTTP interaction",
47
+ "to replay and is prevented from recording new requests. There are a few ways",
48
+ "you can deal with this:\n"].join("\n")
49
+ else
50
+ ["There is currently no cassette in use. There are a few ways",
51
+ "you can configure VCR to handle this request:\n"].join("\n")
52
+ end
53
+ end
54
+
55
+ def formatted_suggestions
56
+ formatted_points, formatted_foot_notes = [], []
57
+
58
+ suggestions.each_with_index do |suggestion, index|
59
+ bullet_point, foot_note = suggestion.first, suggestion.last
60
+ formatted_points << format_bullet_point(bullet_point, index)
61
+ formatted_foot_notes << format_foot_note(foot_note, index)
62
+ end
63
+
64
+ [
65
+ formatted_points.join("\n"),
66
+ formatted_foot_notes.join("\n")
67
+ ].join("\n\n")
68
+ end
69
+
70
+ def format_bullet_point(lines, index)
71
+ lines.first.insert(0, " * ")
72
+ lines.last << " [#{index + 1}]."
73
+ lines.join("\n ")
74
+ end
75
+
76
+ def format_foot_note(url, index)
77
+ "[#{index + 1}] #{url % relish_version_slug}"
78
+ end
79
+
80
+ ALL_SUGGESTIONS = {
81
+ :use_new_episodes => [
82
+ ["You can use the :new_episodes record mode to allow VCR to",
83
+ "record this new request to the existing cassette"],
84
+ "https://www.relishapp.com/myronmarston/vcr/v/%s/docs/record-modes/new-episodes"
85
+ ],
86
+
87
+ :delete_cassette_for_once => [
88
+ ["The current record mode (:once) does not allow new requests to be recorded",
89
+ "to a previously recorded cassette. You can delete the cassette file and re-run",
90
+ "your tests to allow the cassette to be recorded with this request"],
91
+ "https://www.relishapp.com/myronmarston/vcr/v/%s/docs/record-modes/once"
92
+ ],
93
+
94
+ :deal_with_none => [
95
+ ["The current record mode (:none) does not allow requests to be recorded. You",
96
+ "can temporarily change the record mode to :once, delete the cassette file ",
97
+ "and re-run your tests to allow the cassette to be recorded with this request"],
98
+ "https://www.relishapp.com/myronmarston/vcr/v/%s/docs/record-modes/none"
99
+ ],
100
+
101
+ :use_a_cassette => [
102
+ ["If you want VCR to record this request and play it back during future test",
103
+ "runs, you should wrap your test (or this portion of your test) in a",
104
+ "`VCR.use_cassette` block"],
105
+ "https://www.relishapp.com/myronmarston/vcr/v/%s/docs/getting-started"
106
+ ],
107
+
108
+ :allow_http_connections_when_no_cassette => [
109
+ ["If you only want VCR to handle requests made while a cassette is in use,",
110
+ "configure `allow_http_connections_when_no_cassette = true`. VCR will",
111
+ "ignore this request since it is made when there is no cassette"],
112
+ "https://www.relishapp.com/myronmarston/vcr/v/%s/docs/configuration/allow-http-connections-when-no-cassette"
113
+ ],
114
+
115
+ :ignore_request => [
116
+ ["If you want VCR to ignore this request (and others like it), you can",
117
+ "set an `ignore_request` callback"],
118
+ "https://www.relishapp.com/myronmarston/vcr/v/%s/docs/configuration/ignore-request"
119
+ ],
120
+
121
+ :allow_playback_repeats => [
122
+ ["The cassette contains an HTTP interaction that matches this request,",
123
+ "but it has already been played back. If you wish to allow a single HTTP",
124
+ "interaction to be played back multiple times, set the `:allow_playback_repeats`",
125
+ "cassette option"],
126
+ "https://www.relishapp.com/myronmarston/vcr/v/%s/docs/request-matching/playback-repeats"
127
+ ],
128
+
129
+ :match_requests_on => [
130
+ ["The cassette contains %s not been",
131
+ "played back. If your request is non-deterministic, you may need to",
132
+ "change your :match_requests_on cassette option to be more lenient",
133
+ "or use a custom request matcher to allow it to match"],
134
+ "https://www.relishapp.com/myronmarston/vcr/v/%s/docs/request-matching"
135
+ ]
136
+ }
137
+
138
+ def suggestion_for(key)
139
+ bullet_point_lines, url = ALL_SUGGESTIONS[key]
140
+ bullet_point_lines = bullet_point_lines.map(&:dup)
141
+ url = url.dup
142
+ [bullet_point_lines, url]
143
+ end
144
+
145
+ def suggestions
146
+ return no_cassette_suggestions unless cassette = VCR.current_cassette
147
+
148
+ [:use_new_episodes, :ignore_request].tap do |suggestions|
149
+ suggestions.push(*record_mode_suggestion)
150
+ suggestions << :allow_playback_repeats if cassette.http_interactions.has_used_interaction_matching?(request)
151
+ suggestions.map! { |k| suggestion_for(k) }
152
+ suggestions.push(*match_requests_on_suggestion)
153
+ end
154
+ end
155
+
156
+ def no_cassette_suggestions
157
+ [:use_a_cassette, :allow_http_connections_when_no_cassette, :ignore_request].map do |key|
158
+ suggestion_for(key)
159
+ end
160
+ end
161
+
162
+ def record_mode_suggestion
163
+ case VCR.current_cassette.record_mode
164
+ when :none then [:deal_with_none]
165
+ when :once then [:delete_cassette_for_once]
166
+ else []
167
+ end
18
168
  end
169
+
170
+ def match_requests_on_suggestion
171
+ num_remaining_interactions = VCR.current_cassette.http_interactions.remaining_unused_interaction_count
172
+ return [] if num_remaining_interactions.zero?
173
+
174
+ interaction_description = if num_remaining_interactions == 1
175
+ "1 HTTP interaction that has"
176
+ else
177
+ "#{num_remaining_interactions} HTTP interactions that have"
178
+ end
179
+
180
+ description_lines, link = suggestion_for(:match_requests_on)
181
+ description_lines[0] = description_lines[0] % interaction_description
182
+ [[description_lines, link]]
183
+ end
184
+
19
185
  end
20
186
  end
21
187
  end
@@ -1,18 +1,16 @@
1
1
  module VCR
2
2
  class LibraryHooks
3
- def initialize
4
- @exclusive_hook = nil
5
- end
3
+ attr_accessor :exclusive_hook
6
4
 
7
5
  def disabled?(hook)
8
- ![nil, hook].include?(@exclusive_hook)
6
+ ![nil, hook].include?(exclusive_hook)
9
7
  end
10
8
 
11
9
  def exclusively_enabled(hook)
12
- @exclusive_hook = hook
10
+ self.exclusive_hook = hook
13
11
  yield
14
12
  ensure
15
- @exclusive_hook = nil
13
+ self.exclusive_hook = nil
16
14
  end
17
15
  end
18
16
  end
@@ -2,7 +2,7 @@ require 'vcr/util/version_checker'
2
2
  require 'vcr/request_handler'
3
3
  require 'excon'
4
4
 
5
- VCR::VersionChecker.new('Excon', Excon::VERSION, '0.6.5', '0.6').check_version!
5
+ VCR::VersionChecker.new('Excon', Excon::VERSION, '0.6.5', '0.7').check_version!
6
6
 
7
7
  module VCR
8
8
  class LibraryHooks
@@ -10,12 +10,20 @@ module VCR
10
10
  class RequestHandler < ::VCR::RequestHandler
11
11
  attr_reader :params
12
12
  def initialize(params)
13
+ @vcr_response = nil
13
14
  @params = params
14
15
  end
15
16
 
17
+ def handle
18
+ super
19
+ ensure
20
+ invoke_after_request_hook(@vcr_response)
21
+ end
22
+
16
23
  private
17
24
 
18
25
  def on_stubbed_request
26
+ @vcr_response = stubbed_response
19
27
  {
20
28
  :body => stubbed_response.body,
21
29
  :headers => normalized_headers(stubbed_response.headers || {}),
@@ -23,6 +31,10 @@ module VCR
23
31
  }
24
32
  end
25
33
 
34
+ def on_ignored_request
35
+ perform_real_request
36
+ end
37
+
26
38
  def response_from_excon_error(error)
27
39
  if error.respond_to?(:response)
28
40
  error.response
@@ -34,20 +46,18 @@ module VCR
34
46
  end
35
47
 
36
48
  def perform_real_request
37
- connection = ::Excon.new(uri)
38
-
39
- response = begin
40
- connection.request(params.merge(:mock => false))
41
- rescue ::Excon::Errors::Error => e
42
- yield response_from_excon_error(e) if block_given?
43
- raise e
49
+ begin
50
+ response = ::Excon.new(uri).request(params.merge(:mock => false))
51
+ rescue ::Excon::Errors::Error => excon_error
52
+ response = response_from_excon_error(excon_error)
44
53
  end
45
54
 
55
+ @vcr_response = vcr_response_from(response)
46
56
  yield response if block_given?
57
+ raise excon_error if excon_error
47
58
 
48
59
  response.attributes
49
60
  end
50
- alias on_ignored_request perform_real_request
51
61
 
52
62
  def on_recordable_request
53
63
  perform_real_request do |response|
@@ -60,6 +70,8 @@ module VCR
60
70
  @uri ||= "#{params[:scheme]}://#{params[:host]}:#{params[:port]}#{params[:path]}#{query}"
61
71
  end
62
72
 
73
+ # based on:
74
+ # https://github.com/geemus/excon/blob/v0.7.8/lib/excon/connection.rb#L117-132
63
75
  def query
64
76
  @query ||= case params[:query]
65
77
  when String
@@ -84,7 +96,7 @@ module VCR
84
96
  def http_interaction_for(response)
85
97
  VCR::HTTPInteraction.new \
86
98
  vcr_request,
87
- vcr_response(response)
99
+ vcr_response_from(response)
88
100
  end
89
101
 
90
102
  def vcr_request
@@ -100,7 +112,7 @@ module VCR
100
112
  end
101
113
  end
102
114
 
103
- def vcr_response(response)
115
+ def vcr_response_from(response)
104
116
  VCR::Response.new \
105
117
  VCR::ResponseStatus.new(response.status, nil),
106
118
  response.headers,
@@ -3,6 +3,7 @@ require 'fakeweb'
3
3
  require 'net/http'
4
4
  require 'vcr/extensions/net_http_response'
5
5
  require 'vcr/request_handler'
6
+ require 'set'
6
7
 
7
8
  VCR::VersionChecker.new('FakeWeb', FakeWeb::VERSION, '1.3.0', '1.3').check_version!
8
9
 
@@ -10,39 +11,84 @@ module VCR
10
11
  class LibraryHooks
11
12
  module FakeWeb
12
13
  class RequestHandler < ::VCR::RequestHandler
13
- attr_reader :net_http, :request, :request_body, :block
14
- def initialize(net_http, request, request_body = nil, &block)
15
- @net_http, @request, @request_body, @block =
16
- net_http, request, request_body, block
14
+ attr_reader :net_http, :request, :request_body, :response_block
15
+ def initialize(net_http, request, request_body = nil, &response_block)
16
+ @net_http, @request, @request_body, @response_block =
17
+ net_http, request, request_body, response_block
18
+ @vcr_response, @recursing = nil, false
17
19
  end
18
20
 
19
- private
21
+ def handle
22
+ super
23
+ ensure
24
+ invoke_after_request_hook(@vcr_response) unless @recursing
25
+ end
20
26
 
21
- def perform_and_record_request
22
- # Net::HTTP calls #request recursively in certain circumstances.
23
- # We only want to record hte request when the request is started, as
24
- # that is the final time through #request.
25
- return perform_request unless net_http.started?
27
+ class << self
28
+ def already_seen_requests
29
+ @already_seen_requests ||= Set.new
30
+ end
31
+ end
26
32
 
27
- perform_request do |response|
28
- VCR.record_http_interaction VCR::HTTPInteraction.new(vcr_request, vcr_response_from(response))
29
- response.extend VCR::Net::HTTPResponse # "unwind" the response
30
- block.call(response) if block
33
+ private
34
+
35
+ def invoke_before_request_hook
36
+ unless self.class.already_seen_requests.include?(request.object_id)
37
+ super
38
+ # we use the object_id so that if there is bug that causes
39
+ # us not to fully cleanup, we'll only be leaking the memory
40
+ # of one integer, not the whole request object.
41
+ self.class.already_seen_requests << request.object_id
31
42
  end
32
43
  end
33
- alias on_recordable_request perform_and_record_request
34
44
 
35
- def perform_stubbed_request
45
+ def invoke_after_request_hook(vcr_response)
46
+ self.class.already_seen_requests.delete(request.object_id)
47
+ super
48
+ end
49
+
50
+ def on_recordable_request
51
+ perform_request(net_http.started?, :record_interaction)
52
+ end
53
+
54
+ def on_stubbed_request
36
55
  with_exclusive_fakeweb_stub(stubbed_response) do
37
- perform_request
56
+ # force it to be considered started since it doesn't
57
+ # recurse in this case like the others.
58
+ perform_request(:started)
38
59
  end
39
60
  end
40
- alias on_stubbed_request perform_stubbed_request
41
61
 
42
- def perform_request(&record_block)
43
- net_http.request_without_vcr(request, request_body, &(record_block || block))
62
+ def on_ignored_request
63
+ perform_request(net_http.started?)
64
+ end
65
+
66
+ # overriden to prevent it from invoking the after_http_request hook,
67
+ # since we invoke the hook in an ensure block above.
68
+ def on_connection_not_allowed
69
+ raise VCR::Errors::UnhandledHTTPRequestError.new(vcr_request)
70
+ end
71
+
72
+ def perform_request(started, record_interaction = false)
73
+ # Net::HTTP calls #request recursively in certain circumstances.
74
+ # We only want to record the request when the request is started, as
75
+ # that is the final time through #request.
76
+ unless started
77
+ @recursing = true
78
+ return net_http.request_without_vcr(request, request_body, &response_block)
79
+ end
80
+
81
+ net_http.request_without_vcr(request, request_body) do |response|
82
+ @vcr_response = vcr_response_from(response)
83
+
84
+ if record_interaction
85
+ VCR.record_http_interaction VCR::HTTPInteraction.new(vcr_request, @vcr_response)
86
+ end
87
+
88
+ response.extend VCR::Net::HTTPResponse # "unwind" the response
89
+ response_block.call(response) if response_block
90
+ end
44
91
  end
45
- alias on_ignored_request perform_request
46
92
 
47
93
  def uri
48
94
  @uri ||= ::FakeWeb::Utility.request_uri_as_string(net_http, request)
@@ -91,9 +137,13 @@ module Net
91
137
  class HTTP
92
138
  unless method_defined?(:request_with_vcr)
93
139
  def request_with_vcr(*args, &block)
94
- VCR::LibraryHooks::FakeWeb::RequestHandler.new(
95
- self, *args, &block
96
- ).handle
140
+ if VCR.turned_on?
141
+ VCR::LibraryHooks::FakeWeb::RequestHandler.new(
142
+ self, *args, &block
143
+ ).handle
144
+ else
145
+ request_without_vcr(*args, &block)
146
+ end
97
147
  end
98
148
 
99
149
  alias request_without_vcr request
@@ -102,6 +152,17 @@ module Net
102
152
  end
103
153
  end
104
154
 
155
+ class << FakeWeb
156
+ # ensure HTTP requests are always allowed; VCR takes care of disallowing
157
+ # them at the appropriate times in its hook
158
+ def allow_net_connect_with_vcr?(*args)
159
+ VCR.turned_on? ? true : allow_net_connect_without_vcr?
160
+ end
161
+
162
+ alias allow_net_connect_without_vcr? allow_net_connect?
163
+ alias allow_net_connect? allow_net_connect_with_vcr?
164
+ end unless FakeWeb.respond_to?(:allow_net_connect_with_vcr?)
165
+
105
166
  VCR.configuration.after_library_hooks_loaded do
106
167
  if defined?(WebMock)
107
168
  raise ArgumentError.new("You have configured VCR to hook into both :fakeweb and :webmock. You cannot use both.")