vcr 2.0.0.rc2 → 2.0.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.
- data/.travis.yml +2 -0
- data/CHANGELOG.md +19 -2
- data/README.md +17 -5
- data/Upgrade.md +33 -0
- data/benchmarks/http_stubbing_libraries.rb +2 -2
- data/features/getting_started.md +1 -1
- data/features/http_libraries/em_http_request.feature +6 -3
- data/lib/vcr.rb +46 -47
- data/lib/vcr/cassette.rb +16 -3
- data/lib/vcr/configuration.rb +146 -138
- data/lib/vcr/library_hooks/excon.rb +1 -1
- data/lib/vcr/library_hooks/faraday.rb +1 -1
- data/lib/vcr/middleware/faraday.rb +1 -1
- data/lib/vcr/structs.rb +79 -72
- data/lib/vcr/version.rb +1 -1
- data/spec/quality_spec.rb +51 -0
- data/spec/vcr/cassette/migrator_spec.rb +33 -33
- data/spec/vcr/configuration_spec.rb +13 -1
- data/spec/vcr/library_hooks/faraday_spec.rb +0 -1
- data/vcr.gemspec +4 -4
- metadata +51 -42
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,23 @@
|
|
1
1
|
## In git
|
2
2
|
|
3
|
-
[Full Changelog](http://github.com/myronmarston/vcr/compare/v2.0.0
|
3
|
+
[Full Changelog](http://github.com/myronmarston/vcr/compare/v2.0.0...master)
|
4
|
+
|
5
|
+
## 2.0.0 (March 2, 2012)
|
6
|
+
|
7
|
+
[Full Changelog](http://github.com/myronmarston/vcr/compare/v2.0.0.rc2...v2.0.0)
|
8
|
+
|
9
|
+
* Add some additional logged events for the `debug_logger`.
|
10
|
+
* Don't worry about stripping the standard port from the request URI on
|
11
|
+
playback. The standard port only needs to be stripped during recording;
|
12
|
+
for playback, it will have already been stripped. This allows people
|
13
|
+
to use the `filter_sensitive_data` option in a way that changes the URI;
|
14
|
+
before this change, doing so could result in `URI::InvalidURIError`.
|
15
|
+
Thanks to [Patrick Schmitz](https://github.com/bullfight) and
|
16
|
+
[Dan Thompson](https://github.com/danthompson) for reporting the issue
|
17
|
+
and helping diagnose it.
|
18
|
+
* Relax Excon dependency to include newly released 0.10.
|
19
|
+
* Relax Faraday dependency to include 0.8.
|
20
|
+
* Fix Faraday library hook so that it always does the version checking.
|
4
21
|
|
5
22
|
## 2.0.0 RC 2 (February 23, 2012)
|
6
23
|
|
@@ -479,7 +496,7 @@ upgrade notes for more info.
|
|
479
496
|
* New Features
|
480
497
|
* Added support for [HTTPClient](http://github.com/nahi/httpclient), [Patron](http://github.com/toland/patron) and
|
481
498
|
[em-http-request](http://github.com/igrigorik/em-http-request) when WebMock is used. Any future http libraries
|
482
|
-
WebMock supports should (theoretically, at least) work without any VCR code changes. Thanks to
|
499
|
+
WebMock supports should (theoretically, at least) work without any VCR code changes. Thanks to
|
483
500
|
[Bartosz Blimke](http://github.com/bblimke) for adding the necessary code to WebMock to make this happen!
|
484
501
|
* Added support for dynamic responses using ERB. A cassette will be evaluated as ERB before the YAML
|
485
502
|
is deserialized if you pass it an `:erb => true` option. You can pass variables using
|
data/README.md
CHANGED
@@ -69,15 +69,23 @@ maintenance) and accurate (the response will contain the same headers and body y
|
|
69
69
|
|
70
70
|
## Usage
|
71
71
|
|
72
|
-
|
72
|
+
The docs come in two flavors:
|
73
73
|
|
74
|
-
The [
|
75
|
-
|
74
|
+
* The [relish docs](http://relishapp.com/myronmarston/vcr) contain
|
75
|
+
example-based documentation (VCR's cucumber suite, in fact). It's a
|
76
|
+
good place to look when you are first getting started with VCR, or if
|
77
|
+
you want to see an example of how to use a feature.
|
78
|
+
* The [rubydoc.info docs](http://rubydoc.info/gems/vcr/frames) contain
|
79
|
+
API documentation. The API docs contain detailed info about all of VCR's
|
80
|
+
public API.
|
81
|
+
|
82
|
+
See the [Upgrade](https://github.com/myronmarston/vcr/blob/master/Upgrade.md) doc
|
83
|
+
for info about what's new and changed in VCR 2.0.
|
76
84
|
|
77
85
|
## Release Policy
|
78
86
|
|
79
87
|
VCR follows the principles of [semantic versioning](http://semver.org/).
|
80
|
-
The [
|
88
|
+
The [API documentation](http://rubydoc.info/gems/vcr/frames) define
|
81
89
|
VCR's public API. Patch level releases contain only bug fixes. Minor
|
82
90
|
releases contain backward-compatible new features. Major new releases
|
83
91
|
contain backwards-incompatible changes to the public API.
|
@@ -88,10 +96,13 @@ VCR has been tested on the following ruby interpreters:
|
|
88
96
|
|
89
97
|
* MRI 1.8.7
|
90
98
|
* MRI 1.9.2
|
99
|
+
* MRI 1.9.3
|
91
100
|
* REE 1.8.7
|
92
101
|
* JRuby
|
93
102
|
* Rubinius
|
94
103
|
|
104
|
+
Note that as of VCR 2, 1.8.6 and 1.9.1 are not supported.
|
105
|
+
|
95
106
|
## Development
|
96
107
|
|
97
108
|
* Source hosted on [GitHub](http://github.com/myronmarston/vcr).
|
@@ -158,4 +169,5 @@ Thanks also to the following people who have contributed patches or helpful sugg
|
|
158
169
|
|
159
170
|
## Copyright
|
160
171
|
|
161
|
-
Copyright (c) 2010-2012 Myron Marston.
|
172
|
+
Copyright (c) 2010-2012 Myron Marston. Released under the terms of the
|
173
|
+
MIT license. See LICENSE for details.
|
data/Upgrade.md
CHANGED
@@ -220,6 +220,39 @@ the philosophy of VCR to record the entire sequence of HTTP interactions
|
|
220
220
|
interaction can only be played back once unless you use the new
|
221
221
|
`:allow_playback_repeats` option.
|
222
222
|
|
223
|
+
In VCR 1.x, request matching was delegated to the HTTP stubbing library
|
224
|
+
(typically FakeWeb or WebMock). They contain some normalization logic
|
225
|
+
that can treat some URIs that are different strings as equivalent.
|
226
|
+
For example, WebMock ignores the ordering of query parameters:
|
227
|
+
|
228
|
+
``` ruby
|
229
|
+
> require 'webmock'
|
230
|
+
=> true
|
231
|
+
> uri1 = "http://foo.com/bar?a=1&b=2"
|
232
|
+
=> "http://foo.com/bar?a=1&b=2"
|
233
|
+
> uri2 = "http://foo.com/bar?b=2&a=1"
|
234
|
+
=> "http://foo.com/bar?b=2&a=1"
|
235
|
+
> uri1 == uri2
|
236
|
+
=> false
|
237
|
+
> WebMock::Util::URI.normalize_uri(uri1) == WebMock::Util::URI.normalize_uri(uri2)
|
238
|
+
=> true
|
239
|
+
```
|
240
|
+
|
241
|
+
VCR 2, the `:uri` matcher simply [uses string
|
242
|
+
equality](https://github.com/myronmarston/vcr/blob/v2.0.0/lib/vcr/request_matcher_registry.rb#L111).
|
243
|
+
This means that there are some cases of non-deterministic URIs that VCR
|
244
|
+
1.x matched but VCR 2.0 will not match. If you need the `:uri` matcher
|
245
|
+
to be tolerant of slight variations like these, you can easily override
|
246
|
+
it:
|
247
|
+
|
248
|
+
``` ruby
|
249
|
+
VCR.configure do |c|
|
250
|
+
c.register_request_matcher(:uri) do |r1, r2|
|
251
|
+
WebMock::Util::URI.normalize_uri(r1.uri) == WebMock::Util::URI.normalize_uri(r2.uri)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
```
|
255
|
+
|
223
256
|
## Preserve Exact Body Bytes
|
224
257
|
|
225
258
|
Sometimes the request or response body of an HTTP interaction cannot
|
@@ -52,8 +52,8 @@ end
|
|
52
52
|
# Benchmarking Single setup/teardown:
|
53
53
|
# webmock 0.000000 0.000000 6.950000 ( 6.981525)
|
54
54
|
# fakeweb 0.000000 0.010000 1.750000 ( 1.740679)
|
55
|
-
#
|
56
|
-
#
|
55
|
+
#
|
56
|
+
#
|
57
57
|
# Benchmarking Setup/teardown for each http request:
|
58
58
|
# webmock 0.000000 0.000000 7.970000 ( 7.981383)
|
59
59
|
# fakeweb 0.000000 0.000000 2.210000 ( 2.203478)
|
data/features/getting_started.md
CHANGED
@@ -145,13 +145,16 @@ Feature: EM HTTP Request
|
|
145
145
|
multi = EventMachine::MultiRequest.new
|
146
146
|
|
147
147
|
%w[ foo bar bazz ].each do |path|
|
148
|
-
multi.add(EventMachine::HttpRequest.new("http://localhost:7777/#{path}").get)
|
148
|
+
multi.add(path, EventMachine::HttpRequest.new("http://localhost:7777/#{path}").get)
|
149
149
|
end
|
150
150
|
|
151
151
|
multi.callback do
|
152
|
-
multi.responses[:
|
153
|
-
|
152
|
+
responses = Hash[multi.responses[:callback]]
|
153
|
+
|
154
|
+
%w[ foo bar bazz ].each do |path|
|
155
|
+
puts responses[path].response
|
154
156
|
end
|
157
|
+
|
155
158
|
EventMachine.stop
|
156
159
|
end
|
157
160
|
end
|
data/lib/vcr.rb
CHANGED
@@ -153,43 +153,6 @@ module VCR
|
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
156
|
-
# @private
|
157
|
-
def http_interactions
|
158
|
-
return current_cassette.http_interactions if current_cassette
|
159
|
-
VCR::Cassette::HTTPInteractionList::NullList
|
160
|
-
end
|
161
|
-
|
162
|
-
# @private
|
163
|
-
def real_http_connections_allowed?
|
164
|
-
return current_cassette.recording? if current_cassette
|
165
|
-
configuration.allow_http_connections_when_no_cassette? || @turned_off
|
166
|
-
end
|
167
|
-
|
168
|
-
# @return [RequestMatcherRegistry] the request matcher registry
|
169
|
-
def request_matchers
|
170
|
-
@request_matchers ||= RequestMatcherRegistry.new
|
171
|
-
end
|
172
|
-
|
173
|
-
# @private
|
174
|
-
def request_ignorer
|
175
|
-
@request_ignorer ||= RequestIgnorer.new
|
176
|
-
end
|
177
|
-
|
178
|
-
# @private
|
179
|
-
def library_hooks
|
180
|
-
@library_hooks ||= LibraryHooks.new
|
181
|
-
end
|
182
|
-
|
183
|
-
# @private
|
184
|
-
def cassette_serializers
|
185
|
-
@cassette_serializers ||= Cassette::Serializers.new
|
186
|
-
end
|
187
|
-
|
188
|
-
# @return [VCR::Configuration] the VCR configuration.
|
189
|
-
def configuration
|
190
|
-
@configuration ||= Configuration.new
|
191
|
-
end
|
192
|
-
|
193
156
|
# Used to configure VCR.
|
194
157
|
#
|
195
158
|
# @example
|
@@ -204,6 +167,11 @@ module VCR
|
|
204
167
|
yield configuration
|
205
168
|
end
|
206
169
|
|
170
|
+
# @return [VCR::Configuration] the VCR configuration.
|
171
|
+
def configuration
|
172
|
+
@configuration ||= Configuration.new
|
173
|
+
end
|
174
|
+
|
207
175
|
# Sets up `Before` and `After` cucumber hooks in order to
|
208
176
|
# use VCR with particular cucumber tags.
|
209
177
|
#
|
@@ -222,14 +190,6 @@ module VCR
|
|
222
190
|
yield VCR::CucumberTags.new(main_object)
|
223
191
|
end
|
224
192
|
|
225
|
-
# @private
|
226
|
-
def record_http_interaction(interaction)
|
227
|
-
return unless cassette = current_cassette
|
228
|
-
return if VCR.request_ignorer.ignore?(interaction.request)
|
229
|
-
|
230
|
-
cassette.record_http_interaction(interaction)
|
231
|
-
end
|
232
|
-
|
233
193
|
# Turns VCR off for the duration of a block.
|
234
194
|
#
|
235
195
|
# @param (see #turn_off!)
|
@@ -292,12 +252,51 @@ module VCR
|
|
292
252
|
end
|
293
253
|
|
294
254
|
# @private
|
295
|
-
def
|
296
|
-
|
255
|
+
def http_interactions
|
256
|
+
return current_cassette.http_interactions if current_cassette
|
257
|
+
VCR::Cassette::HTTPInteractionList::NullList
|
258
|
+
end
|
259
|
+
|
260
|
+
# @private
|
261
|
+
def real_http_connections_allowed?
|
262
|
+
return current_cassette.recording? if current_cassette
|
263
|
+
configuration.allow_http_connections_when_no_cassette? || @turned_off
|
264
|
+
end
|
265
|
+
|
266
|
+
# @return [RequestMatcherRegistry] the request matcher registry
|
267
|
+
def request_matchers
|
268
|
+
@request_matchers ||= RequestMatcherRegistry.new
|
269
|
+
end
|
270
|
+
|
271
|
+
# @private
|
272
|
+
def request_ignorer
|
273
|
+
@request_ignorer ||= RequestIgnorer.new
|
274
|
+
end
|
275
|
+
|
276
|
+
# @private
|
277
|
+
def library_hooks
|
278
|
+
@library_hooks ||= LibraryHooks.new
|
279
|
+
end
|
280
|
+
|
281
|
+
# @private
|
282
|
+
def cassette_serializers
|
283
|
+
@cassette_serializers ||= Cassette::Serializers.new
|
284
|
+
end
|
285
|
+
|
286
|
+
# @private
|
287
|
+
def record_http_interaction(interaction)
|
288
|
+
return unless cassette = current_cassette
|
289
|
+
return if VCR.request_ignorer.ignore?(interaction.request)
|
290
|
+
|
291
|
+
cassette.record_http_interaction(interaction)
|
297
292
|
end
|
298
293
|
|
299
294
|
private
|
300
295
|
|
296
|
+
def ignore_cassettes?
|
297
|
+
@ignore_cassettes
|
298
|
+
end
|
299
|
+
|
301
300
|
def cassettes
|
302
301
|
@cassettes ||= []
|
303
302
|
end
|
data/lib/vcr/cassette.rb
CHANGED
@@ -156,11 +156,24 @@ module VCR
|
|
156
156
|
|
157
157
|
def should_re_record?
|
158
158
|
return false unless @re_record_interval
|
159
|
-
|
159
|
+
previously_recorded_at = earliest_interaction_recorded_at
|
160
|
+
return false unless previously_recorded_at
|
160
161
|
return false unless File.exist?(file)
|
161
|
-
return false unless InternetConnection.available?
|
162
162
|
|
163
|
-
|
163
|
+
now = Time.now
|
164
|
+
|
165
|
+
(previously_recorded_at + @re_record_interval < now).tap do |value|
|
166
|
+
info = "previously recorded at: '#{previously_recorded_at}'; now: '#{now}'; interval: #{@re_record_interval} seconds"
|
167
|
+
|
168
|
+
if !value
|
169
|
+
log "Not re-recording since the interval has not elapsed (#{info})."
|
170
|
+
elsif InternetConnection.available?
|
171
|
+
log "re-recording (#{info})."
|
172
|
+
else
|
173
|
+
log "Not re-recording because no internet connection is available (#{info})."
|
174
|
+
return false
|
175
|
+
end
|
176
|
+
end
|
164
177
|
end
|
165
178
|
|
166
179
|
def earliest_interaction_recorded_at
|
data/lib/vcr/configuration.rb
CHANGED
@@ -4,119 +4,9 @@ require 'vcr/util/hooks'
|
|
4
4
|
module VCR
|
5
5
|
# Stores the VCR configuration.
|
6
6
|
class Configuration
|
7
|
-
include
|
8
|
-
include
|
9
|
-
|
10
|
-
# Adds a callback that will be called before the recorded HTTP interactions
|
11
|
-
# are serialized and written to disk.
|
12
|
-
#
|
13
|
-
# @example
|
14
|
-
# VCR.configure do |c|
|
15
|
-
# # Don't record transient 5xx errors
|
16
|
-
# c.before_record do |interaction|
|
17
|
-
# interaction.ignore! if interaction.response.status.code >= 500
|
18
|
-
# end
|
19
|
-
#
|
20
|
-
# # Modify the response body for cassettes tagged with :twilio
|
21
|
-
# c.before_record(:twilio) do |interaction|
|
22
|
-
# interaction.response.body.downcase!
|
23
|
-
# end
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# @param tag [(optional) Symbol] Used to apply this hook to only cassettes that match
|
27
|
-
# the given tag.
|
28
|
-
# @yield the callback
|
29
|
-
# @yieldparam interaction [VCR::HTTPInteraction::HookAware] The interaction that will be
|
30
|
-
# serialized and written to disk.
|
31
|
-
# @yieldparam cassette [(optional) VCR::Cassette] The current cassette.
|
32
|
-
# @see #before_playback
|
33
|
-
define_hook :before_record
|
34
|
-
def before_record(tag = nil, &block)
|
35
|
-
super(filter_from(tag), &block)
|
36
|
-
end
|
37
|
-
|
38
|
-
# Adds a callback that will be called before a previously recorded
|
39
|
-
# HTTP interaction is loaded for playback.
|
40
|
-
#
|
41
|
-
# @example
|
42
|
-
# VCR.configure do |c|
|
43
|
-
# # Don't playback transient 5xx errors
|
44
|
-
# c.before_playback do |interaction|
|
45
|
-
# interaction.ignore! if interaction.response.status.code >= 500
|
46
|
-
# end
|
47
|
-
#
|
48
|
-
# # Change a response header for playback
|
49
|
-
# c.before_playback(:twilio) do |interaction|
|
50
|
-
# interaction.response.headers['X-Foo-Bar'] = 'Bazz'
|
51
|
-
# end
|
52
|
-
# end
|
53
|
-
#
|
54
|
-
# @param tag [(optional) Symbol] Used to apply this hook to only cassettes that match
|
55
|
-
# the given tag.
|
56
|
-
# @yield the callback
|
57
|
-
# @yieldparam interaction [VCR::HTTPInteraction::HookAware] The interaction that is being
|
58
|
-
# loaded.
|
59
|
-
# @yieldparam cassette [(optional) VCR::Cassette] The current cassette.
|
60
|
-
# @see #before_record
|
61
|
-
define_hook :before_playback
|
62
|
-
def before_playback(tag = nil, &block)
|
63
|
-
super(filter_from(tag), &block)
|
64
|
-
end
|
65
|
-
|
66
|
-
# @private
|
67
|
-
define_hook :after_library_hooks_loaded
|
68
|
-
|
69
|
-
# Adds a callback that will be called with each HTTP request before it is made.
|
70
|
-
#
|
71
|
-
# @example
|
72
|
-
# VCR.configure do |c|
|
73
|
-
# c.before_http_request(:real?) do |request|
|
74
|
-
# puts "Request: #{request.method} #{request.uri}"
|
75
|
-
# end
|
76
|
-
# end
|
77
|
-
#
|
78
|
-
# @param filters [optional splat of #to_proc] one or more filters to apply.
|
79
|
-
# The objects provided will be converted to procs using `#to_proc`. If provided,
|
80
|
-
# the callback will only be invoked if these procs all return `true`.
|
81
|
-
# @yield the callback
|
82
|
-
# @yieldparam request [VCR::Request::Typed] the request that is being made
|
83
|
-
# @see #after_http_request
|
84
|
-
# @see #around_http_request
|
85
|
-
define_hook :before_http_request
|
86
|
-
|
87
|
-
# Adds a callback that will be called with each HTTP request after it is complete.
|
88
|
-
#
|
89
|
-
# @example
|
90
|
-
# VCR.configure do |c|
|
91
|
-
# c.after_http_request(:ignored?) do |request, response|
|
92
|
-
# puts "Request: #{request.method} #{request.uri}"
|
93
|
-
# puts "Response: #{response.status.code}"
|
94
|
-
# end
|
95
|
-
# end
|
96
|
-
#
|
97
|
-
# @param filters [optional splat of #to_proc] one or more filters to apply.
|
98
|
-
# The objects provided will be converted to procs using `#to_proc`. If provided,
|
99
|
-
# the callback will only be invoked if these procs all return `true`.
|
100
|
-
# @yield the callback
|
101
|
-
# @yieldparam request [VCR::Request::Typed] the request that is being made
|
102
|
-
# @yieldparam response [VCR::Response] the response from the request
|
103
|
-
# @see #before_http_request
|
104
|
-
# @see #around_http_request
|
105
|
-
define_hook :after_http_request, :prepend
|
106
|
-
|
107
|
-
# @private
|
108
|
-
def initialize
|
109
|
-
@allow_http_connections_when_no_cassette = nil
|
110
|
-
@default_cassette_options = {
|
111
|
-
:record => :once,
|
112
|
-
:match_requests_on => RequestMatcherRegistry::DEFAULT_MATCHERS,
|
113
|
-
:serialize_with => :yaml
|
114
|
-
}
|
115
|
-
|
116
|
-
self.debug_logger = NullDebugLogger
|
117
|
-
|
118
|
-
register_built_in_hooks
|
119
|
-
end
|
7
|
+
include Hooks
|
8
|
+
include VariableArgsBlockCaller
|
9
|
+
include Logger
|
120
10
|
|
121
11
|
# The directory to read cassettes from and write cassettes to.
|
122
12
|
#
|
@@ -175,29 +65,6 @@ module VCR
|
|
175
65
|
invoke_hook(:after_library_hooks_loaded)
|
176
66
|
end
|
177
67
|
|
178
|
-
# Registers a request matcher for later use.
|
179
|
-
#
|
180
|
-
# @example
|
181
|
-
# VCR.configure do |c|
|
182
|
-
# c.register_request_matcher :port do |request_1, request_2|
|
183
|
-
# URI(request_1.uri).port == URI(request_2.uri).port
|
184
|
-
# end
|
185
|
-
# end
|
186
|
-
#
|
187
|
-
# VCR.use_cassette("my_cassette", :match_requests_on => [:method, :host, :port]) do
|
188
|
-
# # ...
|
189
|
-
# end
|
190
|
-
#
|
191
|
-
# @param name [Symbol] the name of the request matcher
|
192
|
-
# @yield the request matcher
|
193
|
-
# @yieldparam request_1 [VCR::Request] One request
|
194
|
-
# @yieldparam request_2 [VCR::Request] The other request
|
195
|
-
# @yieldreturn [Boolean] whether or not these two requests should be considered
|
196
|
-
# equivalent
|
197
|
-
def register_request_matcher(name, &block)
|
198
|
-
VCR.request_matchers.register(name, &block)
|
199
|
-
end
|
200
|
-
|
201
68
|
# Specifies host(s) that VCR should ignore.
|
202
69
|
#
|
203
70
|
# @param hosts [Array<String>] List of hosts to ignore
|
@@ -254,6 +121,29 @@ module VCR
|
|
254
121
|
!!@allow_http_connections_when_no_cassette
|
255
122
|
end
|
256
123
|
|
124
|
+
# Registers a request matcher for later use.
|
125
|
+
#
|
126
|
+
# @example
|
127
|
+
# VCR.configure do |c|
|
128
|
+
# c.register_request_matcher :port do |request_1, request_2|
|
129
|
+
# URI(request_1.uri).port == URI(request_2.uri).port
|
130
|
+
# end
|
131
|
+
# end
|
132
|
+
#
|
133
|
+
# VCR.use_cassette("my_cassette", :match_requests_on => [:method, :host, :port]) do
|
134
|
+
# # ...
|
135
|
+
# end
|
136
|
+
#
|
137
|
+
# @param name [Symbol] the name of the request matcher
|
138
|
+
# @yield the request matcher
|
139
|
+
# @yieldparam request_1 [VCR::Request] One request
|
140
|
+
# @yieldparam request_2 [VCR::Request] The other request
|
141
|
+
# @yieldreturn [Boolean] whether or not these two requests should be considered
|
142
|
+
# equivalent
|
143
|
+
def register_request_matcher(name, &block)
|
144
|
+
VCR.request_matchers.register(name, &block)
|
145
|
+
end
|
146
|
+
|
257
147
|
# Sets up a {#before_record} and a {#before_playback} hook that will
|
258
148
|
# insert a placeholder string in the cassette in place of another string.
|
259
149
|
# You can use this as a generic way to interpolate a variable into the
|
@@ -279,11 +169,15 @@ module VCR
|
|
279
169
|
# @yieldreturn the string to replace
|
280
170
|
def define_cassette_placeholder(placeholder, tag = nil, &block)
|
281
171
|
before_record(tag) do |interaction|
|
282
|
-
|
172
|
+
orig_text = call_block(block, interaction)
|
173
|
+
log "before_record: replacing #{orig_text.inspect} with #{placeholder.inspect}"
|
174
|
+
interaction.filter!(orig_text, placeholder)
|
283
175
|
end
|
284
176
|
|
285
177
|
before_playback(tag) do |interaction|
|
286
|
-
|
178
|
+
orig_text = call_block(block, interaction)
|
179
|
+
log "before_playback: replacing #{placeholder.inspect} with #{orig_text.inspect}"
|
180
|
+
interaction.filter!(placeholder, orig_text)
|
287
181
|
end
|
288
182
|
end
|
289
183
|
alias filter_sensitive_data define_cassette_placeholder
|
@@ -305,6 +199,100 @@ module VCR
|
|
305
199
|
VCR.cassette_serializers
|
306
200
|
end
|
307
201
|
|
202
|
+
# Adds a callback that will be called before the recorded HTTP interactions
|
203
|
+
# are serialized and written to disk.
|
204
|
+
#
|
205
|
+
# @example
|
206
|
+
# VCR.configure do |c|
|
207
|
+
# # Don't record transient 5xx errors
|
208
|
+
# c.before_record do |interaction|
|
209
|
+
# interaction.ignore! if interaction.response.status.code >= 500
|
210
|
+
# end
|
211
|
+
#
|
212
|
+
# # Modify the response body for cassettes tagged with :twilio
|
213
|
+
# c.before_record(:twilio) do |interaction|
|
214
|
+
# interaction.response.body.downcase!
|
215
|
+
# end
|
216
|
+
# end
|
217
|
+
#
|
218
|
+
# @param tag [(optional) Symbol] Used to apply this hook to only cassettes that match
|
219
|
+
# the given tag.
|
220
|
+
# @yield the callback
|
221
|
+
# @yieldparam interaction [VCR::HTTPInteraction::HookAware] The interaction that will be
|
222
|
+
# serialized and written to disk.
|
223
|
+
# @yieldparam cassette [(optional) VCR::Cassette] The current cassette.
|
224
|
+
# @see #before_playback
|
225
|
+
define_hook :before_record
|
226
|
+
def before_record(tag = nil, &block)
|
227
|
+
super(filter_from(tag), &block)
|
228
|
+
end
|
229
|
+
|
230
|
+
# Adds a callback that will be called before a previously recorded
|
231
|
+
# HTTP interaction is loaded for playback.
|
232
|
+
#
|
233
|
+
# @example
|
234
|
+
# VCR.configure do |c|
|
235
|
+
# # Don't playback transient 5xx errors
|
236
|
+
# c.before_playback do |interaction|
|
237
|
+
# interaction.ignore! if interaction.response.status.code >= 500
|
238
|
+
# end
|
239
|
+
#
|
240
|
+
# # Change a response header for playback
|
241
|
+
# c.before_playback(:twilio) do |interaction|
|
242
|
+
# interaction.response.headers['X-Foo-Bar'] = 'Bazz'
|
243
|
+
# end
|
244
|
+
# end
|
245
|
+
#
|
246
|
+
# @param tag [(optional) Symbol] Used to apply this hook to only cassettes that match
|
247
|
+
# the given tag.
|
248
|
+
# @yield the callback
|
249
|
+
# @yieldparam interaction [VCR::HTTPInteraction::HookAware] The interaction that is being
|
250
|
+
# loaded.
|
251
|
+
# @yieldparam cassette [(optional) VCR::Cassette] The current cassette.
|
252
|
+
# @see #before_record
|
253
|
+
define_hook :before_playback
|
254
|
+
def before_playback(tag = nil, &block)
|
255
|
+
super(filter_from(tag), &block)
|
256
|
+
end
|
257
|
+
|
258
|
+
# Adds a callback that will be called with each HTTP request before it is made.
|
259
|
+
#
|
260
|
+
# @example
|
261
|
+
# VCR.configure do |c|
|
262
|
+
# c.before_http_request(:real?) do |request|
|
263
|
+
# puts "Request: #{request.method} #{request.uri}"
|
264
|
+
# end
|
265
|
+
# end
|
266
|
+
#
|
267
|
+
# @param filters [optional splat of #to_proc] one or more filters to apply.
|
268
|
+
# The objects provided will be converted to procs using `#to_proc`. If provided,
|
269
|
+
# the callback will only be invoked if these procs all return `true`.
|
270
|
+
# @yield the callback
|
271
|
+
# @yieldparam request [VCR::Request::Typed] the request that is being made
|
272
|
+
# @see #after_http_request
|
273
|
+
# @see #around_http_request
|
274
|
+
define_hook :before_http_request
|
275
|
+
|
276
|
+
# Adds a callback that will be called with each HTTP request after it is complete.
|
277
|
+
#
|
278
|
+
# @example
|
279
|
+
# VCR.configure do |c|
|
280
|
+
# c.after_http_request(:ignored?) do |request, response|
|
281
|
+
# puts "Request: #{request.method} #{request.uri}"
|
282
|
+
# puts "Response: #{response.status.code}"
|
283
|
+
# end
|
284
|
+
# end
|
285
|
+
#
|
286
|
+
# @param filters [optional splat of #to_proc] one or more filters to apply.
|
287
|
+
# The objects provided will be converted to procs using `#to_proc`. If provided,
|
288
|
+
# the callback will only be invoked if these procs all return `true`.
|
289
|
+
# @yield the callback
|
290
|
+
# @yieldparam request [VCR::Request::Typed] the request that is being made
|
291
|
+
# @yieldparam response [VCR::Response] the response from the request
|
292
|
+
# @see #before_http_request
|
293
|
+
# @see #around_http_request
|
294
|
+
define_hook :after_http_request, :prepend
|
295
|
+
|
308
296
|
# Adds a callback that will be executed around each HTTP request.
|
309
297
|
#
|
310
298
|
# @example
|
@@ -405,6 +393,19 @@ module VCR
|
|
405
393
|
|
406
394
|
private
|
407
395
|
|
396
|
+
def initialize
|
397
|
+
@allow_http_connections_when_no_cassette = nil
|
398
|
+
@default_cassette_options = {
|
399
|
+
:record => :once,
|
400
|
+
:match_requests_on => RequestMatcherRegistry::DEFAULT_MATCHERS,
|
401
|
+
:serialize_with => :yaml
|
402
|
+
}
|
403
|
+
|
404
|
+
self.debug_logger = NullDebugLogger
|
405
|
+
|
406
|
+
register_built_in_hooks
|
407
|
+
end
|
408
|
+
|
408
409
|
def load_library_hook(hook)
|
409
410
|
file = "vcr/library_hooks/#{hook}"
|
410
411
|
require file
|
@@ -445,6 +446,13 @@ module VCR
|
|
445
446
|
cassette && cassette.tags.include?(:preserve_exact_body_bytes)
|
446
447
|
end
|
447
448
|
end
|
449
|
+
|
450
|
+
def log_prefix
|
451
|
+
"[VCR::Configuration] "
|
452
|
+
end
|
453
|
+
|
454
|
+
# @private
|
455
|
+
define_hook :after_library_hooks_loaded
|
448
456
|
end
|
449
457
|
|
450
458
|
# @private
|