vcr 2.0.0.rc1 → 2.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/.gitignore +2 -0
  2. data/.limited_red +1 -0
  3. data/.travis.yml +10 -1
  4. data/.yardopts +9 -0
  5. data/CHANGELOG.md +51 -1
  6. data/Gemfile +5 -1
  7. data/LICENSE +1 -1
  8. data/README.md +23 -28
  9. data/Rakefile +63 -18
  10. data/Upgrade.md +200 -0
  11. data/features/.nav +2 -0
  12. data/features/cassettes/automatic_re_recording.feature +19 -15
  13. data/features/cassettes/dynamic_erb.feature +12 -4
  14. data/features/cassettes/exclusive.feature +31 -23
  15. data/features/cassettes/format.feature +54 -30
  16. data/features/cassettes/naming.feature +1 -1
  17. data/features/cassettes/update_content_length_header.feature +16 -12
  18. data/features/configuration/allow_http_connections_when_no_cassette.feature +1 -1
  19. data/features/configuration/debug_logging.feature +52 -0
  20. data/features/configuration/filter_sensitive_data.feature +4 -4
  21. data/features/configuration/hook_into.feature +5 -2
  22. data/features/configuration/ignore_request.feature +5 -3
  23. data/features/configuration/preserve_exact_body_bytes.feature +103 -0
  24. data/features/hooks/after_http_request.feature +17 -4
  25. data/features/hooks/around_http_request.feature +2 -1
  26. data/features/hooks/before_http_request.feature +25 -8
  27. data/features/hooks/before_playback.feature +16 -12
  28. data/features/hooks/before_record.feature +2 -2
  29. data/features/http_libraries/em_http_request.feature +82 -58
  30. data/features/http_libraries/net_http.feature +6 -6
  31. data/features/middleware/faraday.feature +2 -1
  32. data/features/middleware/rack.feature +2 -2
  33. data/features/record_modes/all.feature +19 -15
  34. data/features/record_modes/new_episodes.feature +17 -13
  35. data/features/record_modes/none.feature +15 -11
  36. data/features/record_modes/once.feature +16 -12
  37. data/features/request_matching/body.feature +28 -20
  38. data/features/request_matching/custom_matcher.feature +28 -20
  39. data/features/request_matching/headers.feature +34 -26
  40. data/features/request_matching/host.feature +28 -20
  41. data/features/request_matching/identical_request_sequence.feature +28 -20
  42. data/features/request_matching/method.feature +28 -20
  43. data/features/request_matching/path.feature +28 -20
  44. data/features/request_matching/playback_repeats.feature +28 -20
  45. data/features/request_matching/uri.feature +28 -20
  46. data/features/request_matching/uri_without_param.feature +28 -20
  47. data/features/support/env.rb +7 -6
  48. data/features/support/vcr_cucumber_helpers.rb +1 -0
  49. data/features/test_frameworks/cucumber.feature +8 -8
  50. data/features/test_frameworks/rspec_macro.feature +4 -4
  51. data/features/test_frameworks/rspec_metadata.feature +6 -6
  52. data/features/test_frameworks/shoulda.feature +1 -1
  53. data/features/test_frameworks/test_unit.feature +1 -1
  54. data/lib/vcr.rb +156 -5
  55. data/lib/vcr/cassette.rb +80 -30
  56. data/lib/vcr/cassette/http_interaction_list.rb +33 -4
  57. data/lib/vcr/cassette/migrator.rb +2 -3
  58. data/lib/vcr/cassette/reader.rb +1 -0
  59. data/lib/vcr/cassette/serializers.rb +22 -0
  60. data/lib/vcr/cassette/serializers/json.rb +27 -2
  61. data/lib/vcr/cassette/serializers/psych.rb +26 -2
  62. data/lib/vcr/cassette/serializers/syck.rb +28 -2
  63. data/lib/vcr/cassette/serializers/yaml.rb +28 -2
  64. data/lib/vcr/configuration.rb +348 -10
  65. data/lib/vcr/deprecations.rb +8 -0
  66. data/lib/vcr/errors.rb +40 -0
  67. data/lib/vcr/extensions/net_http_response.rb +12 -11
  68. data/lib/vcr/library_hooks.rb +1 -0
  69. data/lib/vcr/library_hooks/excon.rb +24 -3
  70. data/lib/vcr/library_hooks/fakeweb.rb +32 -16
  71. data/lib/vcr/library_hooks/faraday.rb +3 -0
  72. data/lib/vcr/library_hooks/typhoeus.rb +40 -37
  73. data/lib/vcr/library_hooks/webmock.rb +54 -34
  74. data/lib/vcr/middleware/faraday.rb +13 -0
  75. data/lib/vcr/middleware/rack.rb +35 -0
  76. data/lib/vcr/request_handler.rb +60 -8
  77. data/lib/vcr/request_ignorer.rb +1 -0
  78. data/lib/vcr/request_matcher_registry.rb +28 -0
  79. data/lib/vcr/structs.rb +245 -38
  80. data/lib/vcr/test_frameworks/cucumber.rb +10 -0
  81. data/lib/vcr/test_frameworks/rspec.rb +26 -1
  82. data/lib/vcr/util/hooks.rb +29 -27
  83. data/lib/vcr/util/internet_connection.rb +2 -0
  84. data/lib/vcr/util/logger.rb +25 -0
  85. data/lib/vcr/util/variable_args_block_caller.rb +1 -0
  86. data/lib/vcr/util/version_checker.rb +1 -0
  87. data/lib/vcr/version.rb +8 -1
  88. data/spec/capture_warnings.rb +3 -3
  89. data/spec/monkey_patches.rb +28 -13
  90. data/spec/spec_helper.rb +17 -0
  91. data/spec/support/http_library_adapters.rb +7 -4
  92. data/spec/support/shared_example_groups/hook_into_http_library.rb +96 -32
  93. data/spec/support/shared_example_groups/request_hooks.rb +9 -8
  94. data/spec/support/sinatra_app.rb +3 -1
  95. data/spec/support/vcr_localhost_server.rb +1 -0
  96. data/spec/vcr/cassette/http_interaction_list_spec.rb +119 -54
  97. data/spec/vcr/cassette/migrator_spec.rb +19 -6
  98. data/spec/vcr/cassette/serializers_spec.rb +51 -6
  99. data/spec/vcr/cassette_spec.rb +44 -19
  100. data/spec/vcr/configuration_spec.rb +91 -6
  101. data/spec/vcr/library_hooks/excon_spec.rb +54 -16
  102. data/spec/vcr/library_hooks/fakeweb_spec.rb +12 -21
  103. data/spec/vcr/library_hooks/typhoeus_spec.rb +2 -29
  104. data/spec/vcr/library_hooks/webmock_spec.rb +4 -18
  105. data/spec/vcr/middleware/faraday_spec.rb +1 -16
  106. data/spec/vcr/structs_spec.rb +194 -61
  107. data/spec/vcr/test_frameworks/rspec_spec.rb +10 -0
  108. data/spec/vcr/util/hooks_spec.rb +104 -56
  109. data/spec/vcr/util/version_checker_spec.rb +45 -0
  110. data/spec/vcr_spec.rb +11 -0
  111. data/vcr.gemspec +30 -34
  112. metadata +149 -95
  113. data/spec/support/shared_example_groups/version_checking.rb +0 -34
@@ -1,15 +1,19 @@
1
1
  module VCR
2
+ # @deprecated Use #configure instead.
3
+ # @see #configure
2
4
  def config
3
5
  warn "WARNING: `VCR.config` is deprecated. Use VCR.configure instead."
4
6
  configure { |c| yield c }
5
7
  end
6
8
 
9
+ # @private
7
10
  def self.const_missing(const)
8
11
  return super unless const == :Config
9
12
  warn "WARNING: `VCR::Config` is deprecated. Use VCR.configuration instead."
10
13
  configuration
11
14
  end
12
15
 
16
+ # @private
13
17
  def Cassette.const_missing(const)
14
18
  return super unless const == :MissingERBVariableError
15
19
  warn "WARNING: `VCR::Cassette::MissingERBVariableError` is deprecated. Use `VCR::Errors::MissingERBVariableError` instead."
@@ -17,14 +21,18 @@ module VCR
17
21
  end
18
22
 
19
23
  class Configuration
24
+ # @deprecated Use #hook_into instead.
25
+ # @see #hook_into
20
26
  def stub_with(*adapters)
21
27
  warn "WARNING: `VCR.config { |c| c.stub_with ... }` is deprecated. Use `VCR.configure { |c| c.hook_into ... }` instead."
22
28
  hook_into(*adapters)
23
29
  end
24
30
  end
25
31
 
32
+ # @private
26
33
  module Deprecations
27
34
  module Middleware
35
+ # @private
28
36
  module Faraday
29
37
  def initialize(*args)
30
38
  if block_given?
data/lib/vcr/errors.rb CHANGED
@@ -1,18 +1,57 @@
1
1
  module VCR
2
+ # Namespace for VCR errors.
2
3
  module Errors
4
+ # Base class for all VCR errors.
3
5
  class Error < StandardError; end
6
+
7
+ # Error raised when VCR is turned off while a cassette is in use.
8
+ # @see VCR#turn_off!
9
+ # @see VCR#turned_off
4
10
  class CassetteInUseError < Error; end
11
+
12
+ # Error raised when a VCR cassette is inserted while VCR is turned off.
13
+ # @see VCR#insert_cassette
14
+ # @see VCR#use_cassette
5
15
  class TurnedOffError < Error; end
16
+
17
+ # Error raised when an cassette ERB template is rendered and a
18
+ # variable is missing.
19
+ # @see VCR#insert_cassette
20
+ # @see VCR#use_cassette
6
21
  class MissingERBVariableError < Error; end
22
+
23
+ # Error raised when the version of one of the libraries that VCR hooks into
24
+ # is too low for VCR to support.
25
+ # @see VCR::Configuration#hook_into
7
26
  class LibraryVersionTooLowError < Error; end
27
+
28
+ # Error raised when a request matcher is requested that is not registered.
8
29
  class UnregisteredMatcherError < Error; end
30
+
31
+ # Error raised when a VCR 1.x cassette is used with VCR 2.
9
32
  class InvalidCassetteFormatError < Error; end
33
+
34
+ # Error raised when an +around_http_request+ hook is used improperly.
35
+ # @see VCR::Configuration#around_http_request
10
36
  class AroundHTTPRequestHookError < Error; end
37
+
38
+ # Error raised when you attempt to use a VCR feature that is not
39
+ # supported on your ruby interpreter.
40
+ # @see VCR::Configuration#around_http_request
11
41
  class NotSupportedError < Error; end
12
42
 
43
+ # Error raised when an HTTP request is made that VCR is unable to handle.
44
+ # @note VCR will raise this to force you to do something about the
45
+ # HTTP request. The idea is that you want to handle _every_ HTTP
46
+ # request in your test suite. The error message will give you
47
+ # suggestions for how to deal with the request.
13
48
  class UnhandledHTTPRequestError < Error
49
+ # The HTTP request.
14
50
  attr_reader :request
15
51
 
52
+ # Constructs the error.
53
+ #
54
+ # @param [VCR::Request] request the unhandled request.
16
55
  def initialize(request)
17
56
  @request = request
18
57
  super construct_message
@@ -77,6 +116,7 @@ module VCR
77
116
  "[#{index + 1}] #{url % relish_version_slug}"
78
117
  end
79
118
 
119
+ # List of suggestions for how to configure VCR to handle the request.
80
120
  ALL_SUGGESTIONS = {
81
121
  :use_new_episodes => [
82
122
  ["You can use the :new_episodes record mode to allow VCR to",
@@ -1,16 +1,17 @@
1
- # A Net::HTTP response that has already been read raises an IOError when #read_body
2
- # is called with a destination string or block.
3
- #
4
- # This causes a problem when VCR records a response--it reads the body before yielding
5
- # the response, and if the code that is consuming the HTTP requests uses #read_body, it
6
- # can cause an error.
7
- #
8
- # This is a bit of a hack, but it allows a Net::HTTP response to be "re-read"
9
- # after it has aleady been read. This attemps to preserve the behavior of
10
- # #read_body, acting just as if it had never been read.
11
-
12
1
  module VCR
2
+ # @private
13
3
  module Net
4
+ # A Net::HTTP response that has already been read raises an IOError when #read_body
5
+ # is called with a destination string or block.
6
+ #
7
+ # This causes a problem when VCR records a response--it reads the body before yielding
8
+ # the response, and if the code that is consuming the HTTP requests uses #read_body, it
9
+ # can cause an error.
10
+ #
11
+ # This is a bit of a hack, but it allows a Net::HTTP response to be "re-read"
12
+ # after it has aleady been read. This attemps to preserve the behavior of
13
+ # #read_body, acting just as if it had never been read.
14
+ # @private
14
15
  module HTTPResponse
15
16
  def self.extended(response)
16
17
  response.instance_variable_set(:@__read_body_previously_called, false)
@@ -1,4 +1,5 @@
1
1
  module VCR
2
+ # @private
2
3
  class LibraryHooks
3
4
  attr_accessor :exclusive_hook
4
5
 
@@ -2,10 +2,11 @@ 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.7').check_version!
5
+ VCR::VersionChecker.new('Excon', Excon::VERSION, '0.9.6', '0.9').check_version!
6
6
 
7
7
  module VCR
8
8
  class LibraryHooks
9
+ # @private
9
10
  module Excon
10
11
  class RequestHandler < ::VCR::RequestHandler
11
12
  attr_reader :params
@@ -45,9 +46,21 @@ module VCR
45
46
  end
46
47
  end
47
48
 
49
+ def real_request_params
50
+ # Excon supports a variety of options that affect how it handles failure
51
+ # and retry; we don't want to use any options here--we just want to get
52
+ # a raw response, and then the main request (with :mock => true) can
53
+ # handle failure/retry on its own with its set options.
54
+ params.merge(:mock => false, :retry_limit => 0).tap do |p|
55
+ [:expects, :idempotent, :instrumentor_name, :instrumentor].each do |key|
56
+ p.delete(key)
57
+ end
58
+ end
59
+ end
60
+
48
61
  def perform_real_request
49
62
  begin
50
- response = ::Excon.new(uri).request(params.merge(:mock => false))
63
+ response = ::Excon.new(uri).request(real_request_params)
51
64
  rescue ::Excon::Errors::Error => excon_error
52
65
  response = response_from_excon_error(excon_error)
53
66
  end
@@ -138,5 +151,13 @@ module VCR
138
151
  end
139
152
  end
140
153
 
141
- Excon.mock = true
154
+ Excon.defaults[:mock] = true
155
+
156
+ VCR.configuration.after_library_hooks_loaded do
157
+ # ensure WebMock's Excon adapter does not conflict with us here
158
+ # (i.e. to double record requests or whatever).
159
+ if defined?(WebMock::HttpLibAdapters::ExconAdapter)
160
+ WebMock::HttpLibAdapters::ExconAdapter.disable!
161
+ end
162
+ end
142
163
 
@@ -9,13 +9,21 @@ VCR::VersionChecker.new('FakeWeb', FakeWeb::VERSION, '1.3.0', '1.3').check_versi
9
9
 
10
10
  module VCR
11
11
  class LibraryHooks
12
+ # @private
12
13
  module FakeWeb
14
+ # @private
13
15
  class RequestHandler < ::VCR::RequestHandler
14
16
  attr_reader :net_http, :request, :request_body, :response_block
15
17
  def initialize(net_http, request, request_body = nil, &response_block)
16
18
  @net_http, @request, @request_body, @response_block =
17
19
  net_http, request, request_body, response_block
18
20
  @vcr_response, @recursing = nil, false
21
+
22
+ if ([:@__vcr_request_type, "@__vcr_request_type"] & request.instance_variables).any?
23
+ @request_type = request.instance_variable_get(:@__vcr_request_type)
24
+ else
25
+ @request_type = nil
26
+ end
19
27
  end
20
28
 
21
29
  def handle
@@ -32,6 +40,15 @@ module VCR
32
40
 
33
41
  private
34
42
 
43
+ def request_type(*args)
44
+ @request_type || super
45
+ end
46
+
47
+ def set_typed_request_for_after_hook(request_type)
48
+ @request.instance_variable_set(:@__vcr_request_type, request_type)
49
+ super
50
+ end
51
+
35
52
  def invoke_before_request_hook
36
53
  unless self.class.already_seen_requests.include?(request.object_id)
37
54
  super
@@ -63,12 +80,6 @@ module VCR
63
80
  perform_request(net_http.started?)
64
81
  end
65
82
 
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
83
  def perform_request(started, record_interaction = false)
73
84
  # Net::HTTP calls #request recursively in certain circumstances.
74
85
  # We only want to record the request when the request is started, as
@@ -117,7 +128,7 @@ module VCR
117
128
  @vcr_request ||= VCR::Request.new \
118
129
  request.method.downcase.to_sym,
119
130
  uri,
120
- request_body,
131
+ (request_body || request.body),
121
132
  request.to_hash
122
133
  end
123
134
 
@@ -133,7 +144,9 @@ module VCR
133
144
  end
134
145
  end
135
146
 
147
+ # @private
136
148
  module Net
149
+ # @private
137
150
  class HTTP
138
151
  unless method_defined?(:request_with_vcr)
139
152
  def request_with_vcr(*args, &block)
@@ -152,16 +165,19 @@ module Net
152
165
  end
153
166
  end
154
167
 
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
168
+ # @private
169
+ module FakeWeb
170
+ class << self
171
+ # ensure HTTP requests are always allowed; VCR takes care of disallowing
172
+ # them at the appropriate times in its hook
173
+ def allow_net_connect_with_vcr?(*args)
174
+ VCR.turned_on? ? true : allow_net_connect_without_vcr?
175
+ end
161
176
 
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?)
177
+ alias allow_net_connect_without_vcr? allow_net_connect?
178
+ alias allow_net_connect? allow_net_connect_with_vcr?
179
+ end unless respond_to?(:allow_net_connect_with_vcr?)
180
+ end
165
181
 
166
182
  VCR.configuration.after_library_hooks_loaded do
167
183
  if defined?(WebMock)
@@ -2,7 +2,9 @@ require 'faraday'
2
2
 
3
3
  module VCR
4
4
  class LibraryHooks
5
+ # @private
5
6
  module Faraday
7
+ # @private
6
8
  module BuilderClassExtension
7
9
  def new(*args)
8
10
  super.extend BuilderInstanceExtension
@@ -11,6 +13,7 @@ module VCR
11
13
  ::Faraday::Builder.extend self
12
14
  end
13
15
 
16
+ # @private
14
17
  module BuilderInstanceExtension
15
18
  def lock!(*args)
16
19
  insert_vcr_middleware
@@ -6,42 +6,33 @@ VCR::VersionChecker.new('Typhoeus', Typhoeus::VERSION, '0.3.2', '0.3').check_ver
6
6
 
7
7
  module VCR
8
8
  class LibraryHooks
9
+ # @private
9
10
  module Typhoeus
10
- module Helpers
11
- def vcr_request_from(request)
12
- VCR::Request.new \
13
- request.method,
14
- request.url,
15
- request.body,
16
- request.headers
17
- end
18
-
19
- def vcr_response_from(response)
20
- VCR::Response.new \
21
- VCR::ResponseStatus.new(response.code, response.status_message),
22
- response.headers_hash,
23
- response.body,
24
- response.http_version
25
- end
26
- end
27
-
11
+ # @private
28
12
  class RequestHandler < ::VCR::RequestHandler
29
- include Helpers
30
-
31
13
  attr_reader :request
32
14
  def initialize(request)
33
15
  @request = request
34
16
  end
35
17
 
18
+ def vcr_request
19
+ @vcr_request ||= VCR::Request.new \
20
+ request.method,
21
+ request.url,
22
+ request.body,
23
+ request.headers
24
+ end
25
+
36
26
  private
37
27
 
38
- def on_connection_not_allowed
39
- invoke_after_request_hook(nil)
28
+ def set_typed_request_for_after_hook(*args)
40
29
  super
30
+ request.instance_variable_set(:@__typed_vcr_request, @after_hook_typed_request)
41
31
  end
42
32
 
43
- def vcr_request
44
- @vcr_request ||= vcr_request_from(request)
33
+ def on_unhandled_request
34
+ invoke_after_request_hook(nil)
35
+ super
45
36
  end
46
37
 
47
38
  def on_stubbed_request
@@ -62,17 +53,26 @@ module VCR
62
53
  end
63
54
  end
64
55
 
65
- extend Helpers
56
+ # @private
57
+ def self.vcr_response_from(response)
58
+ VCR::Response.new \
59
+ VCR::ResponseStatus.new(response.code, response.status_message),
60
+ response.headers_hash,
61
+ response.body,
62
+ response.http_version
63
+ end
64
+
66
65
  ::Typhoeus::Hydra.after_request_before_on_complete do |request|
67
66
  unless VCR.library_hooks.disabled?(:typhoeus)
68
- vcr_request, vcr_response = vcr_request_from(request), vcr_response_from(request.response)
67
+ vcr_response = vcr_response_from(request.response)
68
+ typed_vcr_request = request.send(:remove_instance_variable, :@__typed_vcr_request)
69
69
 
70
70
  unless request.response.mock?
71
- http_interaction = VCR::HTTPInteraction.new(vcr_request, vcr_response)
71
+ http_interaction = VCR::HTTPInteraction.new(typed_vcr_request, vcr_response)
72
72
  VCR.record_http_interaction(http_interaction)
73
73
  end
74
74
 
75
- VCR.configuration.invoke_hook(:after_http_request, vcr_request, vcr_response)
75
+ VCR.configuration.invoke_hook(:after_http_request, typed_vcr_request, vcr_response)
76
76
  end
77
77
  end
78
78
 
@@ -83,16 +83,19 @@ module VCR
83
83
  end
84
84
  end
85
85
 
86
- class << Typhoeus::Hydra
87
- # ensure HTTP requests are always allowed; VCR takes care of disallowing
88
- # them at the appropriate times in its hook
89
- def allow_net_connect_with_vcr?(*args)
90
- VCR.turned_on? ? true : allow_net_connect_without_vcr?
91
- end
86
+ # @private
87
+ module Typhoeus
88
+ class << Hydra
89
+ # ensure HTTP requests are always allowed; VCR takes care of disallowing
90
+ # them at the appropriate times in its hook
91
+ def allow_net_connect_with_vcr?(*args)
92
+ VCR.turned_on? ? true : allow_net_connect_without_vcr?
93
+ end
92
94
 
93
- alias allow_net_connect_without_vcr? allow_net_connect?
94
- alias allow_net_connect? allow_net_connect_with_vcr?
95
- end unless Typhoeus::Hydra.respond_to?(:allow_net_connect_with_vcr?)
95
+ alias allow_net_connect_without_vcr? allow_net_connect?
96
+ alias allow_net_connect? allow_net_connect_with_vcr?
97
+ end unless Hydra.respond_to?(:allow_net_connect_with_vcr?)
98
+ end
96
99
 
97
100
  VCR.configuration.after_library_hooks_loaded do
98
101
  # ensure WebMock's Typhoeus adapter does not conflict with us here
@@ -2,31 +2,13 @@ require 'vcr/util/version_checker'
2
2
  require 'vcr/request_handler'
3
3
  require 'webmock'
4
4
 
5
- VCR::VersionChecker.new('WebMock', WebMock.version, '1.7.8', '1.7').check_version!
5
+ VCR::VersionChecker.new('WebMock', WebMock.version, '1.8.0', '1.8').check_version!
6
6
 
7
7
  module VCR
8
8
  class LibraryHooks
9
+ # @private
9
10
  module WebMock
10
- module Helpers
11
- def vcr_request_from(webmock_request)
12
- VCR::Request.new \
13
- webmock_request.method,
14
- webmock_request.uri.to_s,
15
- webmock_request.body,
16
- webmock_request.headers
17
- end
18
-
19
- def vcr_response_from(response)
20
- VCR::Response.new \
21
- VCR::ResponseStatus.new(response.status.first, response.status.last),
22
- response.headers,
23
- response.body,
24
- nil
25
- end
26
- end
27
-
28
11
  class RequestHandler < ::VCR::RequestHandler
29
- include Helpers
30
12
 
31
13
  attr_reader :request
32
14
  def initialize(request)
@@ -35,11 +17,38 @@ module VCR
35
17
 
36
18
  private
37
19
 
20
+ def set_typed_request_for_after_hook(*args)
21
+ super
22
+ request.instance_variable_set(:@__typed_vcr_request, @after_hook_typed_request)
23
+ end
24
+
38
25
  def vcr_request
39
- @vcr_request ||= vcr_request_from(request)
26
+ @vcr_request ||= VCR::Request.new \
27
+ request.method,
28
+ request.uri.to_s,
29
+ request.body,
30
+ request_headers
31
+ end
32
+
33
+ if defined?(::Excon)
34
+ # @private
35
+ def request_headers
36
+ return nil unless request.headers
37
+
38
+ # WebMock hooks deeply into a Excon at a place where it manually adds a "Host"
39
+ # header, but this isn't a header we actually care to store...
40
+ request.headers.dup.tap do |headers|
41
+ headers.delete("Host")
42
+ end
43
+ end
44
+ else
45
+ # @private
46
+ def request_headers
47
+ request.headers
48
+ end
40
49
  end
41
50
 
42
- def on_connection_not_allowed
51
+ def on_unhandled_request
43
52
  invoke_after_request_hook(nil)
44
53
  super
45
54
  end
@@ -53,14 +62,21 @@ module VCR
53
62
  end
54
63
  end
55
64
 
56
- extend Helpers
65
+ # @private
66
+ def self.vcr_response_from(response)
67
+ VCR::Response.new \
68
+ VCR::ResponseStatus.new(response.status.first, response.status.last),
69
+ response.headers,
70
+ response.body,
71
+ nil
72
+ end
57
73
 
58
74
  ::WebMock.globally_stub_request { |req| RequestHandler.new(req).handle }
59
75
 
60
76
  ::WebMock.after_request(:real_requests_only => true) do |request, response|
61
77
  unless VCR.library_hooks.disabled?(:webmock)
62
78
  http_interaction = VCR::HTTPInteraction.new \
63
- vcr_request_from(request),
79
+ request.send(:instance_variable_get, :@__typed_vcr_request),
64
80
  vcr_response_from(response)
65
81
 
66
82
  VCR.record_http_interaction(http_interaction)
@@ -69,21 +85,25 @@ module VCR
69
85
 
70
86
  ::WebMock.after_request do |request, response|
71
87
  unless VCR.library_hooks.disabled?(:webmock)
72
- VCR.configuration.invoke_hook(:after_http_request, vcr_request_from(request), vcr_response_from(response))
88
+ typed_vcr_request = request.send(:remove_instance_variable, :@__typed_vcr_request)
89
+ VCR.configuration.invoke_hook(:after_http_request, typed_vcr_request, vcr_response_from(response))
73
90
  end
74
91
  end
75
92
  end
76
93
  end
77
94
  end
78
95
 
79
- class << WebMock
80
- # ensure HTTP requests are always allowed; VCR takes care of disallowing
81
- # them at the appropriate times in its hook
82
- def net_connect_allowed_with_vcr?(*args)
83
- VCR.turned_on? ? true : net_connect_allowed_without_vcr?
84
- end
96
+ # @private
97
+ module WebMock
98
+ class << self
99
+ # ensure HTTP requests are always allowed; VCR takes care of disallowing
100
+ # them at the appropriate times in its hook
101
+ def net_connect_allowed_with_vcr?(*args)
102
+ VCR.turned_on? ? true : net_connect_allowed_without_vcr?
103
+ end
85
104
 
86
- alias net_connect_allowed_without_vcr? net_connect_allowed?
87
- alias net_connect_allowed? net_connect_allowed_with_vcr?
88
- end unless WebMock.respond_to?(:net_connect_allowed_with_vcr?)
105
+ alias net_connect_allowed_without_vcr? net_connect_allowed?
106
+ alias net_connect_allowed? net_connect_allowed_with_vcr?
107
+ end unless respond_to?(:net_connect_allowed_with_vcr?)
108
+ end
89
109