vcr 2.0.0.rc1 → 2.0.0.rc2
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.
- data/.gitignore +2 -0
- data/.limited_red +1 -0
- data/.travis.yml +10 -1
- data/.yardopts +9 -0
- data/CHANGELOG.md +51 -1
- data/Gemfile +5 -1
- data/LICENSE +1 -1
- data/README.md +23 -28
- data/Rakefile +63 -18
- data/Upgrade.md +200 -0
- data/features/.nav +2 -0
- data/features/cassettes/automatic_re_recording.feature +19 -15
- data/features/cassettes/dynamic_erb.feature +12 -4
- data/features/cassettes/exclusive.feature +31 -23
- data/features/cassettes/format.feature +54 -30
- data/features/cassettes/naming.feature +1 -1
- data/features/cassettes/update_content_length_header.feature +16 -12
- data/features/configuration/allow_http_connections_when_no_cassette.feature +1 -1
- data/features/configuration/debug_logging.feature +52 -0
- data/features/configuration/filter_sensitive_data.feature +4 -4
- data/features/configuration/hook_into.feature +5 -2
- data/features/configuration/ignore_request.feature +5 -3
- data/features/configuration/preserve_exact_body_bytes.feature +103 -0
- data/features/hooks/after_http_request.feature +17 -4
- data/features/hooks/around_http_request.feature +2 -1
- data/features/hooks/before_http_request.feature +25 -8
- data/features/hooks/before_playback.feature +16 -12
- data/features/hooks/before_record.feature +2 -2
- data/features/http_libraries/em_http_request.feature +82 -58
- data/features/http_libraries/net_http.feature +6 -6
- data/features/middleware/faraday.feature +2 -1
- data/features/middleware/rack.feature +2 -2
- data/features/record_modes/all.feature +19 -15
- data/features/record_modes/new_episodes.feature +17 -13
- data/features/record_modes/none.feature +15 -11
- data/features/record_modes/once.feature +16 -12
- data/features/request_matching/body.feature +28 -20
- data/features/request_matching/custom_matcher.feature +28 -20
- data/features/request_matching/headers.feature +34 -26
- data/features/request_matching/host.feature +28 -20
- data/features/request_matching/identical_request_sequence.feature +28 -20
- data/features/request_matching/method.feature +28 -20
- data/features/request_matching/path.feature +28 -20
- data/features/request_matching/playback_repeats.feature +28 -20
- data/features/request_matching/uri.feature +28 -20
- data/features/request_matching/uri_without_param.feature +28 -20
- data/features/support/env.rb +7 -6
- data/features/support/vcr_cucumber_helpers.rb +1 -0
- data/features/test_frameworks/cucumber.feature +8 -8
- data/features/test_frameworks/rspec_macro.feature +4 -4
- data/features/test_frameworks/rspec_metadata.feature +6 -6
- data/features/test_frameworks/shoulda.feature +1 -1
- data/features/test_frameworks/test_unit.feature +1 -1
- data/lib/vcr.rb +156 -5
- data/lib/vcr/cassette.rb +80 -30
- data/lib/vcr/cassette/http_interaction_list.rb +33 -4
- data/lib/vcr/cassette/migrator.rb +2 -3
- data/lib/vcr/cassette/reader.rb +1 -0
- data/lib/vcr/cassette/serializers.rb +22 -0
- data/lib/vcr/cassette/serializers/json.rb +27 -2
- data/lib/vcr/cassette/serializers/psych.rb +26 -2
- data/lib/vcr/cassette/serializers/syck.rb +28 -2
- data/lib/vcr/cassette/serializers/yaml.rb +28 -2
- data/lib/vcr/configuration.rb +348 -10
- data/lib/vcr/deprecations.rb +8 -0
- data/lib/vcr/errors.rb +40 -0
- data/lib/vcr/extensions/net_http_response.rb +12 -11
- data/lib/vcr/library_hooks.rb +1 -0
- data/lib/vcr/library_hooks/excon.rb +24 -3
- data/lib/vcr/library_hooks/fakeweb.rb +32 -16
- data/lib/vcr/library_hooks/faraday.rb +3 -0
- data/lib/vcr/library_hooks/typhoeus.rb +40 -37
- data/lib/vcr/library_hooks/webmock.rb +54 -34
- data/lib/vcr/middleware/faraday.rb +13 -0
- data/lib/vcr/middleware/rack.rb +35 -0
- data/lib/vcr/request_handler.rb +60 -8
- data/lib/vcr/request_ignorer.rb +1 -0
- data/lib/vcr/request_matcher_registry.rb +28 -0
- data/lib/vcr/structs.rb +245 -38
- data/lib/vcr/test_frameworks/cucumber.rb +10 -0
- data/lib/vcr/test_frameworks/rspec.rb +26 -1
- data/lib/vcr/util/hooks.rb +29 -27
- data/lib/vcr/util/internet_connection.rb +2 -0
- data/lib/vcr/util/logger.rb +25 -0
- data/lib/vcr/util/variable_args_block_caller.rb +1 -0
- data/lib/vcr/util/version_checker.rb +1 -0
- data/lib/vcr/version.rb +8 -1
- data/spec/capture_warnings.rb +3 -3
- data/spec/monkey_patches.rb +28 -13
- data/spec/spec_helper.rb +17 -0
- data/spec/support/http_library_adapters.rb +7 -4
- data/spec/support/shared_example_groups/hook_into_http_library.rb +96 -32
- data/spec/support/shared_example_groups/request_hooks.rb +9 -8
- data/spec/support/sinatra_app.rb +3 -1
- data/spec/support/vcr_localhost_server.rb +1 -0
- data/spec/vcr/cassette/http_interaction_list_spec.rb +119 -54
- data/spec/vcr/cassette/migrator_spec.rb +19 -6
- data/spec/vcr/cassette/serializers_spec.rb +51 -6
- data/spec/vcr/cassette_spec.rb +44 -19
- data/spec/vcr/configuration_spec.rb +91 -6
- data/spec/vcr/library_hooks/excon_spec.rb +54 -16
- data/spec/vcr/library_hooks/fakeweb_spec.rb +12 -21
- data/spec/vcr/library_hooks/typhoeus_spec.rb +2 -29
- data/spec/vcr/library_hooks/webmock_spec.rb +4 -18
- data/spec/vcr/middleware/faraday_spec.rb +1 -16
- data/spec/vcr/structs_spec.rb +194 -61
- data/spec/vcr/test_frameworks/rspec_spec.rb +10 -0
- data/spec/vcr/util/hooks_spec.rb +104 -56
- data/spec/vcr/util/version_checker_spec.rb +45 -0
- data/spec/vcr_spec.rb +11 -0
- data/vcr.gemspec +30 -34
- metadata +149 -95
- data/spec/support/shared_example_groups/version_checking.rb +0 -34
data/lib/vcr/deprecations.rb
CHANGED
|
@@ -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)
|
data/lib/vcr/library_hooks.rb
CHANGED
|
@@ -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
|
+
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(
|
|
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
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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
|
-
|
|
163
|
-
|
|
164
|
-
end unless
|
|
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
|
-
|
|
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
|
|
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
|
|
44
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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,
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
end unless
|
|
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.
|
|
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 ||=
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
end unless
|
|
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
|
|