vcr 3.0.2 → 6.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.
- checksums.yaml +5 -5
- data/lib/vcr.rb +33 -1
- data/lib/vcr/cassette.rb +47 -12
- data/lib/vcr/cassette/http_interaction_list.rb +14 -9
- data/lib/vcr/cassette/migrator.rb +0 -5
- data/lib/vcr/cassette/persisters/file_system.rb +9 -1
- data/lib/vcr/cassette/serializers/compressed.rb +2 -2
- data/lib/vcr/cassette/serializers/json.rb +7 -7
- data/lib/vcr/cassette/serializers/psych.rb +3 -1
- data/lib/vcr/cassette/serializers/yaml.rb +3 -1
- data/lib/vcr/configuration.rb +20 -8
- data/lib/vcr/deprecations.rb +0 -62
- data/lib/vcr/errors.rb +17 -12
- data/lib/vcr/library_hooks/excon.rb +8 -0
- data/lib/vcr/library_hooks/typhoeus.rb +37 -8
- data/lib/vcr/linked_cassette.rb +4 -4
- data/lib/vcr/middleware/faraday.rb +10 -1
- data/lib/vcr/request_ignorer.rb +4 -1
- data/lib/vcr/request_matcher_registry.rb +1 -1
- data/lib/vcr/structs.rb +48 -32
- data/lib/vcr/test_frameworks/cucumber.rb +4 -4
- data/lib/vcr/test_frameworks/rspec.rb +12 -3
- data/lib/vcr/util/hooks.rb +1 -0
- data/lib/vcr/util/internet_connection.rb +15 -21
- data/lib/vcr/version.rb +1 -1
- metadata +36 -263
- data/features/CHANGELOG.md +0 -1
- data/features/CONTRIBUTING.md +0 -1
- data/features/LICENSE.md +0 -1
- data/features/README.md +0 -1
- data/features/Upgrade.md +0 -1
- data/features/about_these_examples.md +0 -18
- data/features/cassettes/allow_unused_http_interactions.feature +0 -100
- data/features/cassettes/automatic_re_recording.feature +0 -72
- data/features/cassettes/decompress.feature +0 -74
- data/features/cassettes/dynamic_erb.feature +0 -100
- data/features/cassettes/exclusive.feature +0 -126
- data/features/cassettes/format.feature +0 -411
- data/features/cassettes/freezing_time.feature +0 -68
- data/features/cassettes/naming.feature +0 -28
- data/features/cassettes/no_cassette.feature +0 -152
- data/features/cassettes/update_content_length_header.feature +0 -112
- data/features/configuration/allow_http_connections_when_no_cassette.feature +0 -55
- data/features/configuration/cassette_library_dir.feature +0 -31
- data/features/configuration/debug_logging.feature +0 -58
- data/features/configuration/default_cassette_options.feature +0 -100
- data/features/configuration/filter_sensitive_data.feature +0 -153
- data/features/configuration/hook_into.feature +0 -172
- data/features/configuration/ignore_request.feature +0 -192
- data/features/configuration/preserve_exact_body_bytes.feature +0 -108
- data/features/configuration/query_parser.feature +0 -84
- data/features/configuration/uri_parser.feature +0 -93
- data/features/getting_started.md +0 -82
- data/features/hooks/after_http_request.feature +0 -58
- data/features/hooks/around_http_request.feature +0 -57
- data/features/hooks/before_http_request.feature +0 -63
- data/features/hooks/before_playback.feature +0 -184
- data/features/hooks/before_record.feature +0 -172
- data/features/http_libraries/em_http_request.feature +0 -250
- data/features/http_libraries/net_http.feature +0 -179
- data/features/middleware/faraday.feature +0 -56
- data/features/middleware/rack.feature +0 -92
- data/features/record_modes/all.feature +0 -82
- data/features/record_modes/new_episodes.feature +0 -79
- data/features/record_modes/none.feature +0 -72
- data/features/record_modes/once.feature +0 -95
- data/features/request_matching/README.md +0 -30
- data/features/request_matching/body.feature +0 -91
- data/features/request_matching/body_as_json.feature +0 -90
- data/features/request_matching/custom_matcher.feature +0 -135
- data/features/request_matching/headers.feature +0 -85
- data/features/request_matching/host.feature +0 -95
- data/features/request_matching/identical_request_sequence.feature +0 -89
- data/features/request_matching/method.feature +0 -96
- data/features/request_matching/path.feature +0 -96
- data/features/request_matching/playback_repeats.feature +0 -98
- data/features/request_matching/query.feature +0 -97
- data/features/request_matching/uri.feature +0 -94
- data/features/request_matching/uri_without_param.feature +0 -101
- data/features/step_definitions/cli_steps.rb +0 -199
- data/features/support/env.rb +0 -46
- data/features/support/http_lib_filters.rb +0 -46
- data/features/test_frameworks/cucumber.feature +0 -211
- data/features/test_frameworks/rspec_macro.feature +0 -81
- data/features/test_frameworks/rspec_metadata.feature +0 -150
- data/features/test_frameworks/test_unit.feature +0 -49
- data/lib/vcr/extensions/net_http_response.rb +0 -36
- data/lib/vcr/library_hooks/fakeweb.rb +0 -197
- data/spec/acceptance/concurrency_spec.rb +0 -51
- data/spec/acceptance/threading_spec.rb +0 -34
- data/spec/fixtures/cassette_spec/1_x_cassette.yml +0 -110
- data/spec/fixtures/cassette_spec/empty.yml +0 -0
- data/spec/fixtures/cassette_spec/example.yml +0 -111
- data/spec/fixtures/cassette_spec/with_localhost_requests.yml +0 -111
- data/spec/fixtures/fake_example_responses.yml +0 -110
- data/spec/fixtures/match_requests_on.yml +0 -187
- data/spec/lib/vcr/cassette/erb_renderer_spec.rb +0 -53
- data/spec/lib/vcr/cassette/http_interaction_list_spec.rb +0 -295
- data/spec/lib/vcr/cassette/migrator_spec.rb +0 -196
- data/spec/lib/vcr/cassette/persisters/file_system_spec.rb +0 -75
- data/spec/lib/vcr/cassette/persisters_spec.rb +0 -39
- data/spec/lib/vcr/cassette/serializers_spec.rb +0 -182
- data/spec/lib/vcr/cassette_spec.rb +0 -618
- data/spec/lib/vcr/configuration_spec.rb +0 -326
- data/spec/lib/vcr/deprecations_spec.rb +0 -85
- data/spec/lib/vcr/errors_spec.rb +0 -178
- data/spec/lib/vcr/extensions/net_http_response_spec.rb +0 -86
- data/spec/lib/vcr/library_hooks/excon_spec.rb +0 -104
- data/spec/lib/vcr/library_hooks/fakeweb_spec.rb +0 -169
- data/spec/lib/vcr/library_hooks/faraday_spec.rb +0 -68
- data/spec/lib/vcr/library_hooks/typhoeus_0.4_spec.rb +0 -36
- data/spec/lib/vcr/library_hooks/typhoeus_spec.rb +0 -162
- data/spec/lib/vcr/library_hooks/webmock_spec.rb +0 -117
- data/spec/lib/vcr/library_hooks_spec.rb +0 -51
- data/spec/lib/vcr/middleware/faraday_spec.rb +0 -181
- data/spec/lib/vcr/middleware/rack_spec.rb +0 -115
- data/spec/lib/vcr/request_ignorer_spec.rb +0 -70
- data/spec/lib/vcr/request_matcher_registry_spec.rb +0 -345
- data/spec/lib/vcr/structs_spec.rb +0 -732
- data/spec/lib/vcr/test_frameworks/cucumber_spec.rb +0 -107
- data/spec/lib/vcr/test_frameworks/rspec_spec.rb +0 -94
- data/spec/lib/vcr/util/hooks_spec.rb +0 -158
- data/spec/lib/vcr/util/internet_connection_spec.rb +0 -37
- data/spec/lib/vcr/util/version_checker_spec.rb +0 -31
- data/spec/lib/vcr/version_spec.rb +0 -27
- data/spec/lib/vcr_spec.rb +0 -354
- data/spec/monkey_patches.rb +0 -186
- data/spec/spec_helper.rb +0 -63
- data/spec/support/configuration_stubbing.rb +0 -8
- data/spec/support/cucumber_helpers.rb +0 -39
- data/spec/support/fixnum_extension.rb +0 -10
- data/spec/support/http_library_adapters.rb +0 -289
- data/spec/support/limited_uri.rb +0 -21
- data/spec/support/ruby_interpreter.rb +0 -7
- data/spec/support/shared_example_groups/excon.rb +0 -63
- data/spec/support/shared_example_groups/hook_into_http_library.rb +0 -594
- data/spec/support/shared_example_groups/request_hooks.rb +0 -59
- data/spec/support/sinatra_app.rb +0 -86
- data/spec/support/vcr_localhost_server.rb +0 -76
- data/spec/support/vcr_stub_helpers.rb +0 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 79ff7c5f67afb190b63450e117a7dbda6709340fbab8c17680c36b2bb5a8a6f6
|
|
4
|
+
data.tar.gz: a6a17620c6c63d9a596a39e2700f3f1becddb26bfa63f862e42ef0dfabb783d9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9f43f626bae24850a8b5f912203dba5ee7e38ef39ecb3d325382ca2cbfb24ff789c3e630edd628588fdd59b0a8b10919bedd820675a039b5d619f1c779dc186b
|
|
7
|
+
data.tar.gz: ffc8534bbab227c6f8f4636306644c1c28d1ac8c2d29d47551d1b84c04cd5c37979acfb44803b18c54ee558e961d92826a38e6a75b93d8002af6adde5f2e7d05
|
data/lib/vcr.rb
CHANGED
|
@@ -34,7 +34,6 @@ module VCR
|
|
|
34
34
|
|
|
35
35
|
module RSpec
|
|
36
36
|
autoload :Metadata, 'vcr/test_frameworks/rspec'
|
|
37
|
-
autoload :Macros, 'vcr/deprecations'
|
|
38
37
|
end
|
|
39
38
|
|
|
40
39
|
module Middleware
|
|
@@ -108,6 +107,12 @@ module VCR
|
|
|
108
107
|
# @option options :persist_with [Symbol] Which cassette persister to
|
|
109
108
|
# use. Defaults to :file_system. You can also register and use a
|
|
110
109
|
# custom persister.
|
|
110
|
+
# @option options :persister_options [Hash] Pass options to the
|
|
111
|
+
# persister specified in `persist_with`. Currently available options for the file_system persister:
|
|
112
|
+
# - `:downcase_cassette_names`: when `true`, names of cassettes will be
|
|
113
|
+
# normalized in lowercase before reading and writing, which can avoid
|
|
114
|
+
# confusion when using both case-sensitive and case-insensitive file
|
|
115
|
+
# systems.
|
|
111
116
|
# @option options :preserve_exact_body_bytes [Boolean] Whether or not
|
|
112
117
|
# to base64 encode the bytes of the requests and responses for this cassette
|
|
113
118
|
# when serializing it. See also `VCR::Configuration#preserve_exact_body_bytes`.
|
|
@@ -187,11 +192,35 @@ module VCR
|
|
|
187
192
|
|
|
188
193
|
begin
|
|
189
194
|
call_block(block, cassette)
|
|
195
|
+
rescue StandardError
|
|
196
|
+
cassette.run_failed!
|
|
197
|
+
raise
|
|
190
198
|
ensure
|
|
191
199
|
eject_cassette
|
|
192
200
|
end
|
|
193
201
|
end
|
|
194
202
|
|
|
203
|
+
# Inserts multiple cassettes the given names
|
|
204
|
+
#
|
|
205
|
+
# @example
|
|
206
|
+
# cassettes = [
|
|
207
|
+
# { name: 'github' },
|
|
208
|
+
# { name: 'apple', options: { erb: true } }
|
|
209
|
+
# ]
|
|
210
|
+
# VCR.use_cassettes(cassettes) do
|
|
211
|
+
# # make multiple HTTP requests
|
|
212
|
+
# end
|
|
213
|
+
def use_cassettes(cassettes, &block)
|
|
214
|
+
cassette = cassettes.pop
|
|
215
|
+
use_cassette(cassette[:name], cassette[:options] || {}) do
|
|
216
|
+
if cassettes.empty?
|
|
217
|
+
block.call
|
|
218
|
+
else
|
|
219
|
+
use_cassettes(cassettes, &block)
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
195
224
|
# Used to configure VCR.
|
|
196
225
|
#
|
|
197
226
|
# @example
|
|
@@ -288,6 +317,9 @@ module VCR
|
|
|
288
317
|
# @see #turn_off!
|
|
289
318
|
# @see #turned_off
|
|
290
319
|
def turned_on?
|
|
320
|
+
linked_context = current_context[:linked_context]
|
|
321
|
+
return !linked_context[:turned_off] if linked_context
|
|
322
|
+
|
|
291
323
|
!context_value(:turned_off)
|
|
292
324
|
end
|
|
293
325
|
|
data/lib/vcr/cassette.rb
CHANGED
|
@@ -24,6 +24,13 @@ module VCR
|
|
|
24
24
|
# plays them back, or does both.
|
|
25
25
|
attr_reader :record_mode
|
|
26
26
|
|
|
27
|
+
# @return [Boolean] The cassette's record_on_error mode. When the code that uses the cassette
|
|
28
|
+
# raises an error (for example a test failure) and record_on_error is set to false, no
|
|
29
|
+
# cassette will be recorded. This is useful when you are TDD'ing an API integration: when
|
|
30
|
+
# an error is raised that often means your request is invalid, so you don't want the cassette
|
|
31
|
+
# to be recorded.
|
|
32
|
+
attr_reader :record_on_error
|
|
33
|
+
|
|
27
34
|
# @return [Array<Symbol, #call>] List of request matchers. Used to find a response from an
|
|
28
35
|
# existing HTTP interaction to play back.
|
|
29
36
|
attr_reader :match_requests_on
|
|
@@ -36,6 +43,9 @@ module VCR
|
|
|
36
43
|
# @return [Integer, nil] How frequently (in seconds) the cassette should be re-recorded.
|
|
37
44
|
attr_reader :re_record_interval
|
|
38
45
|
|
|
46
|
+
# @return [Boolean, nil] Should outdated interactions be recorded back to file
|
|
47
|
+
attr_reader :clean_outdated_http_interactions
|
|
48
|
+
|
|
39
49
|
# @return [Array<Symbol>] If set, {VCR::Configuration#before_record} and
|
|
40
50
|
# {VCR::Configuration#before_playback} hooks with a corresponding tag will apply.
|
|
41
51
|
attr_reader :tags
|
|
@@ -45,6 +55,7 @@ module VCR
|
|
|
45
55
|
def initialize(name, options = {})
|
|
46
56
|
@name = name
|
|
47
57
|
@options = VCR.configuration.default_cassette_options.merge(options)
|
|
58
|
+
@mutex = Mutex.new
|
|
48
59
|
|
|
49
60
|
assert_valid_options!
|
|
50
61
|
extract_options
|
|
@@ -62,21 +73,40 @@ module VCR
|
|
|
62
73
|
# @param (see VCR#eject_casssette)
|
|
63
74
|
# @see VCR#eject_cassette
|
|
64
75
|
def eject(options = {})
|
|
65
|
-
write_recorded_interactions_to_disk
|
|
76
|
+
write_recorded_interactions_to_disk if should_write_recorded_interactions_to_disk?
|
|
66
77
|
|
|
67
78
|
if should_assert_no_unused_interactions? && !options[:skip_no_unused_interactions_assertion]
|
|
68
79
|
http_interactions.assert_no_unused_interactions!
|
|
69
80
|
end
|
|
70
81
|
end
|
|
71
82
|
|
|
83
|
+
# @private
|
|
84
|
+
def run_failed!
|
|
85
|
+
@run_failed = true
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# @private
|
|
89
|
+
def run_failed?
|
|
90
|
+
@run_failed = false unless defined?(@run_failed)
|
|
91
|
+
@run_failed
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def should_write_recorded_interactions_to_disk?
|
|
95
|
+
!run_failed? || record_on_error
|
|
96
|
+
end
|
|
97
|
+
|
|
72
98
|
# @private
|
|
73
99
|
def http_interactions
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
@
|
|
78
|
-
|
|
79
|
-
|
|
100
|
+
# Without this mutex, under threaded access, an HTTPInteractionList will overwrite
|
|
101
|
+
# the first.
|
|
102
|
+
@mutex.synchronize do
|
|
103
|
+
@http_interactions ||= HTTPInteractionList.new \
|
|
104
|
+
should_stub_requests? ? previously_recorded_interactions : [],
|
|
105
|
+
match_requests_on,
|
|
106
|
+
@allow_playback_repeats,
|
|
107
|
+
@parent_list,
|
|
108
|
+
log_prefix
|
|
109
|
+
end
|
|
80
110
|
end
|
|
81
111
|
|
|
82
112
|
# @private
|
|
@@ -143,10 +173,10 @@ module VCR
|
|
|
143
173
|
|
|
144
174
|
def assert_valid_options!
|
|
145
175
|
invalid_options = @options.keys - [
|
|
146
|
-
:record, :erb, :match_requests_on, :re_record_interval, :tag, :tags,
|
|
176
|
+
:record, :record_on_error, :erb, :match_requests_on, :re_record_interval, :tag, :tags,
|
|
147
177
|
:update_content_length_header, :allow_playback_repeats, :allow_unused_http_interactions,
|
|
148
178
|
:exclusive, :serialize_with, :preserve_exact_body_bytes, :decode_compressed_response,
|
|
149
|
-
:persist_with
|
|
179
|
+
:recompress_response, :persist_with, :persister_options, :clean_outdated_http_interactions
|
|
150
180
|
]
|
|
151
181
|
|
|
152
182
|
if invalid_options.size > 0
|
|
@@ -155,7 +185,7 @@ module VCR
|
|
|
155
185
|
end
|
|
156
186
|
|
|
157
187
|
def extract_options
|
|
158
|
-
[:erb, :match_requests_on, :re_record_interval,
|
|
188
|
+
[:record_on_error, :erb, :match_requests_on, :re_record_interval, :clean_outdated_http_interactions,
|
|
159
189
|
:allow_playback_repeats, :allow_unused_http_interactions, :exclusive].each do |name|
|
|
160
190
|
instance_variable_set("@#{name}", @options[name])
|
|
161
191
|
end
|
|
@@ -172,7 +202,7 @@ module VCR
|
|
|
172
202
|
def assign_tags
|
|
173
203
|
@tags = Array(@options.fetch(:tags) { @options[:tag] })
|
|
174
204
|
|
|
175
|
-
[:update_content_length_header, :preserve_exact_body_bytes, :decode_compressed_response].each do |tag|
|
|
205
|
+
[:update_content_length_header, :preserve_exact_body_bytes, :decode_compressed_response, :recompress_response].each do |tag|
|
|
176
206
|
@tags << tag if @options[tag]
|
|
177
207
|
end
|
|
178
208
|
end
|
|
@@ -247,7 +277,12 @@ module VCR
|
|
|
247
277
|
end
|
|
248
278
|
end
|
|
249
279
|
|
|
250
|
-
old_interactions + new_recorded_interactions
|
|
280
|
+
up_to_date_interactions(old_interactions) + new_recorded_interactions
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def up_to_date_interactions(interactions)
|
|
284
|
+
return interactions unless clean_outdated_http_interactions && re_record_interval
|
|
285
|
+
interactions.take_while { |x| x[:recorded_at] > Time.now - re_record_interval }
|
|
251
286
|
end
|
|
252
287
|
|
|
253
288
|
def interactions_to_record
|
|
@@ -22,21 +22,26 @@ module VCR
|
|
|
22
22
|
@parent_list = parent_list
|
|
23
23
|
@used_interactions = []
|
|
24
24
|
@log_prefix = log_prefix
|
|
25
|
+
@mutex = Mutex.new
|
|
25
26
|
|
|
26
27
|
interaction_summaries = interactions.map { |i| "#{request_summary(i.request)} => #{response_summary(i.response)}" }
|
|
27
28
|
log "Initialized HTTPInteractionList with request matchers #{request_matchers.inspect} and #{interactions.size} interaction(s): { #{interaction_summaries.join(', ')} }", 1
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
def response_for(request)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
# Without this mutex, under threaded access, the wrong response may be removed
|
|
33
|
+
# out of the (remaining) interactions list (and other problems).
|
|
34
|
+
@mutex.synchronize do
|
|
35
|
+
if index = matching_interaction_index_for(request)
|
|
36
|
+
interaction = @interactions.delete_at(index)
|
|
37
|
+
@used_interactions.unshift interaction
|
|
38
|
+
log "Found matching interaction for #{request_summary(request)} at index #{index}: #{response_summary(interaction.response)}", 1
|
|
39
|
+
interaction.response
|
|
40
|
+
elsif interaction = matching_used_interaction_for(request)
|
|
41
|
+
interaction.response
|
|
42
|
+
else
|
|
43
|
+
@parent_list.response_for(request)
|
|
44
|
+
end
|
|
40
45
|
end
|
|
41
46
|
end
|
|
42
47
|
|
|
@@ -45,11 +45,6 @@ module VCR
|
|
|
45
45
|
"recorded_with" => "VCR #{VCR.version}"
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
def hash.each
|
|
49
|
-
yield 'http_interactions', self['http_interactions']
|
|
50
|
-
yield 'recorded_with', self['recorded_with']
|
|
51
|
-
end
|
|
52
|
-
|
|
53
48
|
File.open(cassette, 'w') { |f| f.write ::YAML.dump(hash) }
|
|
54
49
|
@out.puts " - Migrated #{relative_casssette_name(cassette)}"
|
|
55
50
|
end
|
|
@@ -55,7 +55,15 @@ module VCR
|
|
|
55
55
|
file_extension = '.' + parts.pop
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
parts.join('.').gsub(/[
|
|
58
|
+
file_name = parts.join('.').gsub(/[^[:word:]\-\/]+/, '_') + file_extension.to_s
|
|
59
|
+
file_name.downcase! if downcase_cassette_names?
|
|
60
|
+
file_name
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def downcase_cassette_names?
|
|
64
|
+
!!VCR.configuration
|
|
65
|
+
.default_cassette_options
|
|
66
|
+
.dig(:persister_options, :downcase_cassette_names)
|
|
59
67
|
end
|
|
60
68
|
end
|
|
61
69
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'json'
|
|
2
2
|
|
|
3
3
|
module VCR
|
|
4
4
|
class Cassette
|
|
@@ -13,8 +13,8 @@ module VCR
|
|
|
13
13
|
extend EncodingErrorHandling
|
|
14
14
|
|
|
15
15
|
# @private
|
|
16
|
-
ENCODING_ERRORS = [
|
|
17
|
-
ENCODING_ERRORS <<
|
|
16
|
+
ENCODING_ERRORS = [ArgumentError]
|
|
17
|
+
ENCODING_ERRORS << ::JSON::GeneratorError
|
|
18
18
|
|
|
19
19
|
# The file extension to use for this serializer.
|
|
20
20
|
#
|
|
@@ -23,23 +23,23 @@ module VCR
|
|
|
23
23
|
"json"
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
# Serializes the given hash using `
|
|
26
|
+
# Serializes the given hash using `JSON`.
|
|
27
27
|
#
|
|
28
28
|
# @param [Hash] hash the object to serialize
|
|
29
29
|
# @return [String] the JSON string
|
|
30
30
|
def serialize(hash)
|
|
31
31
|
handle_encoding_errors do
|
|
32
|
-
|
|
32
|
+
::JSON.generate(hash)
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
# Deserializes the given string using `
|
|
36
|
+
# Deserializes the given string using `JSON`.
|
|
37
37
|
#
|
|
38
38
|
# @param [String] string the JSON string
|
|
39
39
|
# @return [Hash] the deserialized object
|
|
40
40
|
def deserialize(string)
|
|
41
41
|
handle_encoding_errors do
|
|
42
|
-
|
|
42
|
+
::JSON.parse(string)
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
end
|
|
@@ -28,7 +28,9 @@ module VCR
|
|
|
28
28
|
# @return [String] the YAML string
|
|
29
29
|
def serialize(hash)
|
|
30
30
|
handle_encoding_errors do
|
|
31
|
-
::Psych.dump(hash)
|
|
31
|
+
result = ::Psych.dump(hash)
|
|
32
|
+
result.gsub!(": \n", ": null\n") # set canonical null value in order to avoid trailing whitespaces
|
|
33
|
+
result
|
|
32
34
|
end
|
|
33
35
|
end
|
|
34
36
|
|
|
@@ -30,7 +30,9 @@ module VCR
|
|
|
30
30
|
# @return [String] the YAML string
|
|
31
31
|
def serialize(hash)
|
|
32
32
|
handle_encoding_errors do
|
|
33
|
-
::YAML.dump(hash)
|
|
33
|
+
result = ::YAML.dump(hash)
|
|
34
|
+
result.gsub!(": \n", ": null\n") # set canonical null value in order to avoid trailing whitespaces
|
|
35
|
+
result
|
|
34
36
|
end
|
|
35
37
|
end
|
|
36
38
|
|
data/lib/vcr/configuration.rb
CHANGED
|
@@ -54,16 +54,14 @@ module VCR
|
|
|
54
54
|
#
|
|
55
55
|
# @example
|
|
56
56
|
# VCR.configure do |c|
|
|
57
|
-
# c.hook_into :
|
|
57
|
+
# c.hook_into :webmock, :typhoeus
|
|
58
58
|
# end
|
|
59
59
|
#
|
|
60
60
|
# @param hooks [Array<Symbol>] List of libraries. Valid values are
|
|
61
|
-
# `:
|
|
61
|
+
# `:webmock`, `:typhoeus`, `:excon` and `:faraday`.
|
|
62
62
|
# @raise [ArgumentError] when given an unsupported library name.
|
|
63
63
|
# @raise [VCR::Errors::LibraryVersionTooLowError] when the version
|
|
64
64
|
# of a library you are using is too low for VCR to support.
|
|
65
|
-
# @note `:fakeweb` and `:webmock` cannot both be used since they both monkey patch
|
|
66
|
-
# `Net::HTTP`. Otherwise, you can use any combination of these.
|
|
67
65
|
def hook_into(*hooks)
|
|
68
66
|
hooks.each { |a| load_library_hook(a) }
|
|
69
67
|
invoke_hook(:after_library_hooks_loaded)
|
|
@@ -79,6 +77,15 @@ module VCR
|
|
|
79
77
|
end
|
|
80
78
|
alias ignore_host ignore_hosts
|
|
81
79
|
|
|
80
|
+
# Specifies host(s) that VCR should stop ignoring.
|
|
81
|
+
#
|
|
82
|
+
# @param hosts [Array<String>] List of hosts to unignore
|
|
83
|
+
# @see #ignore_hosts
|
|
84
|
+
def unignore_hosts(*hosts)
|
|
85
|
+
VCR.request_ignorer.unignore_hosts(*hosts)
|
|
86
|
+
end
|
|
87
|
+
alias unignore_host unignore_hosts
|
|
88
|
+
|
|
82
89
|
# Sets whether or not VCR should ignore localhost requests.
|
|
83
90
|
#
|
|
84
91
|
# @param value [Boolean] the value to set
|
|
@@ -224,7 +231,7 @@ module VCR
|
|
|
224
231
|
|
|
225
232
|
before_playback(tag) do |interaction|
|
|
226
233
|
orig_text = call_block(block, interaction)
|
|
227
|
-
log "before_playback: replacing #{
|
|
234
|
+
log "before_playback: replacing #{orig_text.inspect} with #{placeholder.inspect}"
|
|
228
235
|
interaction.filter!(placeholder, orig_text)
|
|
229
236
|
end
|
|
230
237
|
end
|
|
@@ -485,10 +492,12 @@ module VCR
|
|
|
485
492
|
@rspec_metadata_configured = false
|
|
486
493
|
@default_cassette_options = {
|
|
487
494
|
:record => :once,
|
|
495
|
+
:record_on_error => true,
|
|
488
496
|
:match_requests_on => RequestMatcherRegistry::DEFAULT_MATCHERS,
|
|
489
497
|
:allow_unused_http_interactions => true,
|
|
490
498
|
:serialize_with => :yaml,
|
|
491
|
-
:persist_with => :file_system
|
|
499
|
+
:persist_with => :file_system,
|
|
500
|
+
:persister_options => {}
|
|
492
501
|
}
|
|
493
502
|
|
|
494
503
|
self.uri_parser = URI
|
|
@@ -502,7 +511,7 @@ module VCR
|
|
|
502
511
|
file = "vcr/library_hooks/#{hook}"
|
|
503
512
|
require file
|
|
504
513
|
rescue LoadError => e
|
|
505
|
-
raise e unless e.message.include?(file) # in case
|
|
514
|
+
raise e unless e.message.include?(file) # in case WebMock itself is not available
|
|
506
515
|
raise ArgumentError.new("#{hook.inspect} is not a supported VCR HTTP library hook.")
|
|
507
516
|
end
|
|
508
517
|
|
|
@@ -552,6 +561,10 @@ module VCR
|
|
|
552
561
|
end
|
|
553
562
|
|
|
554
563
|
def register_built_in_hooks
|
|
564
|
+
before_playback(:recompress_response) do |interaction|
|
|
565
|
+
interaction.response.recompress if interaction.response.vcr_decompressed?
|
|
566
|
+
end
|
|
567
|
+
|
|
555
568
|
before_playback(:update_content_length_header) do |interaction|
|
|
556
569
|
interaction.response.update_content_length_header
|
|
557
570
|
end
|
|
@@ -573,4 +586,3 @@ module VCR
|
|
|
573
586
|
define_hook :after_library_hooks_loaded
|
|
574
587
|
end
|
|
575
588
|
end
|
|
576
|
-
|
data/lib/vcr/deprecations.rb
CHANGED
|
@@ -43,67 +43,5 @@ module VCR
|
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
|
-
|
|
47
|
-
module RSpec
|
|
48
|
-
# Contains macro methods to assist with VCR usage. These methods are
|
|
49
|
-
# intended to be used directly in an RSpec example group. To make these
|
|
50
|
-
# available in your RSpec example groups, extend the module in an individual
|
|
51
|
-
# example group, or configure RSpec to extend the module in all example groups.
|
|
52
|
-
#
|
|
53
|
-
# @example
|
|
54
|
-
# RSpec.configure do |c|
|
|
55
|
-
# c.extend VCR::RSpec::Macros
|
|
56
|
-
# end
|
|
57
|
-
#
|
|
58
|
-
module Macros
|
|
59
|
-
def self.extended(base)
|
|
60
|
-
Kernel.warn "WARNING: VCR::RSpec::Macros is deprecated. Use RSpec metadata options instead `:vcr => vcr_options`"
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Sets up a `before` and `after` hook that will insert and eject a
|
|
64
|
-
# cassette, respectively.
|
|
65
|
-
#
|
|
66
|
-
# @example
|
|
67
|
-
# describe "Some API Client" do
|
|
68
|
-
# use_vcr_cassette "some_api", :record => :new_episodes
|
|
69
|
-
# end
|
|
70
|
-
#
|
|
71
|
-
# @param [(optional) String] name the cassette name; it will be inferred by the example
|
|
72
|
-
# group descriptions if not given.
|
|
73
|
-
# @param [(optional) Hash] options the cassette options
|
|
74
|
-
# @deprecated Use RSpec metadata options
|
|
75
|
-
def use_vcr_cassette(*args)
|
|
76
|
-
options = args.last.is_a?(Hash) ? args.pop : {}
|
|
77
|
-
name = args.first || infer_cassette_name
|
|
78
|
-
|
|
79
|
-
before(:each) do
|
|
80
|
-
VCR.insert_cassette(name, options)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
after(:each) do
|
|
84
|
-
VCR.eject_cassette
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
private
|
|
89
|
-
|
|
90
|
-
def infer_cassette_name
|
|
91
|
-
# RSpec 1 exposes #description_parts; use that if its available
|
|
92
|
-
return description_parts.join("/") if respond_to?(:description_parts)
|
|
93
|
-
|
|
94
|
-
# Otherwise use RSpec 2/3 metadata...
|
|
95
|
-
group_descriptions = []
|
|
96
|
-
klass = self
|
|
97
|
-
|
|
98
|
-
while klass.respond_to?(:metadata) && klass.metadata
|
|
99
|
-
group_descriptions << klass.metadata[:description] ||
|
|
100
|
-
klass.metadata[:example_group][:description]
|
|
101
|
-
klass = klass.superclass
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
group_descriptions.compact.reverse.join('/')
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
46
|
end
|
|
109
47
|
|