vcr 3.0.2 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +5 -5
  2. data/lib/vcr.rb +33 -1
  3. data/lib/vcr/cassette.rb +47 -12
  4. data/lib/vcr/cassette/http_interaction_list.rb +14 -9
  5. data/lib/vcr/cassette/migrator.rb +0 -5
  6. data/lib/vcr/cassette/persisters/file_system.rb +9 -1
  7. data/lib/vcr/cassette/serializers/compressed.rb +2 -2
  8. data/lib/vcr/cassette/serializers/json.rb +7 -7
  9. data/lib/vcr/cassette/serializers/psych.rb +3 -1
  10. data/lib/vcr/cassette/serializers/yaml.rb +3 -1
  11. data/lib/vcr/configuration.rb +20 -8
  12. data/lib/vcr/deprecations.rb +0 -62
  13. data/lib/vcr/errors.rb +17 -12
  14. data/lib/vcr/library_hooks/excon.rb +8 -0
  15. data/lib/vcr/library_hooks/typhoeus.rb +37 -8
  16. data/lib/vcr/linked_cassette.rb +4 -4
  17. data/lib/vcr/middleware/faraday.rb +10 -1
  18. data/lib/vcr/request_ignorer.rb +4 -1
  19. data/lib/vcr/request_matcher_registry.rb +1 -1
  20. data/lib/vcr/structs.rb +48 -32
  21. data/lib/vcr/test_frameworks/cucumber.rb +4 -4
  22. data/lib/vcr/test_frameworks/rspec.rb +12 -3
  23. data/lib/vcr/util/hooks.rb +1 -0
  24. data/lib/vcr/util/internet_connection.rb +15 -21
  25. data/lib/vcr/version.rb +1 -1
  26. metadata +36 -263
  27. data/features/CHANGELOG.md +0 -1
  28. data/features/CONTRIBUTING.md +0 -1
  29. data/features/LICENSE.md +0 -1
  30. data/features/README.md +0 -1
  31. data/features/Upgrade.md +0 -1
  32. data/features/about_these_examples.md +0 -18
  33. data/features/cassettes/allow_unused_http_interactions.feature +0 -100
  34. data/features/cassettes/automatic_re_recording.feature +0 -72
  35. data/features/cassettes/decompress.feature +0 -74
  36. data/features/cassettes/dynamic_erb.feature +0 -100
  37. data/features/cassettes/exclusive.feature +0 -126
  38. data/features/cassettes/format.feature +0 -411
  39. data/features/cassettes/freezing_time.feature +0 -68
  40. data/features/cassettes/naming.feature +0 -28
  41. data/features/cassettes/no_cassette.feature +0 -152
  42. data/features/cassettes/update_content_length_header.feature +0 -112
  43. data/features/configuration/allow_http_connections_when_no_cassette.feature +0 -55
  44. data/features/configuration/cassette_library_dir.feature +0 -31
  45. data/features/configuration/debug_logging.feature +0 -58
  46. data/features/configuration/default_cassette_options.feature +0 -100
  47. data/features/configuration/filter_sensitive_data.feature +0 -153
  48. data/features/configuration/hook_into.feature +0 -172
  49. data/features/configuration/ignore_request.feature +0 -192
  50. data/features/configuration/preserve_exact_body_bytes.feature +0 -108
  51. data/features/configuration/query_parser.feature +0 -84
  52. data/features/configuration/uri_parser.feature +0 -93
  53. data/features/getting_started.md +0 -82
  54. data/features/hooks/after_http_request.feature +0 -58
  55. data/features/hooks/around_http_request.feature +0 -57
  56. data/features/hooks/before_http_request.feature +0 -63
  57. data/features/hooks/before_playback.feature +0 -184
  58. data/features/hooks/before_record.feature +0 -172
  59. data/features/http_libraries/em_http_request.feature +0 -250
  60. data/features/http_libraries/net_http.feature +0 -179
  61. data/features/middleware/faraday.feature +0 -56
  62. data/features/middleware/rack.feature +0 -92
  63. data/features/record_modes/all.feature +0 -82
  64. data/features/record_modes/new_episodes.feature +0 -79
  65. data/features/record_modes/none.feature +0 -72
  66. data/features/record_modes/once.feature +0 -95
  67. data/features/request_matching/README.md +0 -30
  68. data/features/request_matching/body.feature +0 -91
  69. data/features/request_matching/body_as_json.feature +0 -90
  70. data/features/request_matching/custom_matcher.feature +0 -135
  71. data/features/request_matching/headers.feature +0 -85
  72. data/features/request_matching/host.feature +0 -95
  73. data/features/request_matching/identical_request_sequence.feature +0 -89
  74. data/features/request_matching/method.feature +0 -96
  75. data/features/request_matching/path.feature +0 -96
  76. data/features/request_matching/playback_repeats.feature +0 -98
  77. data/features/request_matching/query.feature +0 -97
  78. data/features/request_matching/uri.feature +0 -94
  79. data/features/request_matching/uri_without_param.feature +0 -101
  80. data/features/step_definitions/cli_steps.rb +0 -199
  81. data/features/support/env.rb +0 -46
  82. data/features/support/http_lib_filters.rb +0 -46
  83. data/features/test_frameworks/cucumber.feature +0 -211
  84. data/features/test_frameworks/rspec_macro.feature +0 -81
  85. data/features/test_frameworks/rspec_metadata.feature +0 -150
  86. data/features/test_frameworks/test_unit.feature +0 -49
  87. data/lib/vcr/extensions/net_http_response.rb +0 -36
  88. data/lib/vcr/library_hooks/fakeweb.rb +0 -197
  89. data/spec/acceptance/concurrency_spec.rb +0 -51
  90. data/spec/acceptance/threading_spec.rb +0 -34
  91. data/spec/fixtures/cassette_spec/1_x_cassette.yml +0 -110
  92. data/spec/fixtures/cassette_spec/empty.yml +0 -0
  93. data/spec/fixtures/cassette_spec/example.yml +0 -111
  94. data/spec/fixtures/cassette_spec/with_localhost_requests.yml +0 -111
  95. data/spec/fixtures/fake_example_responses.yml +0 -110
  96. data/spec/fixtures/match_requests_on.yml +0 -187
  97. data/spec/lib/vcr/cassette/erb_renderer_spec.rb +0 -53
  98. data/spec/lib/vcr/cassette/http_interaction_list_spec.rb +0 -295
  99. data/spec/lib/vcr/cassette/migrator_spec.rb +0 -196
  100. data/spec/lib/vcr/cassette/persisters/file_system_spec.rb +0 -75
  101. data/spec/lib/vcr/cassette/persisters_spec.rb +0 -39
  102. data/spec/lib/vcr/cassette/serializers_spec.rb +0 -182
  103. data/spec/lib/vcr/cassette_spec.rb +0 -618
  104. data/spec/lib/vcr/configuration_spec.rb +0 -326
  105. data/spec/lib/vcr/deprecations_spec.rb +0 -85
  106. data/spec/lib/vcr/errors_spec.rb +0 -178
  107. data/spec/lib/vcr/extensions/net_http_response_spec.rb +0 -86
  108. data/spec/lib/vcr/library_hooks/excon_spec.rb +0 -104
  109. data/spec/lib/vcr/library_hooks/fakeweb_spec.rb +0 -169
  110. data/spec/lib/vcr/library_hooks/faraday_spec.rb +0 -68
  111. data/spec/lib/vcr/library_hooks/typhoeus_0.4_spec.rb +0 -36
  112. data/spec/lib/vcr/library_hooks/typhoeus_spec.rb +0 -162
  113. data/spec/lib/vcr/library_hooks/webmock_spec.rb +0 -117
  114. data/spec/lib/vcr/library_hooks_spec.rb +0 -51
  115. data/spec/lib/vcr/middleware/faraday_spec.rb +0 -181
  116. data/spec/lib/vcr/middleware/rack_spec.rb +0 -115
  117. data/spec/lib/vcr/request_ignorer_spec.rb +0 -70
  118. data/spec/lib/vcr/request_matcher_registry_spec.rb +0 -345
  119. data/spec/lib/vcr/structs_spec.rb +0 -732
  120. data/spec/lib/vcr/test_frameworks/cucumber_spec.rb +0 -107
  121. data/spec/lib/vcr/test_frameworks/rspec_spec.rb +0 -94
  122. data/spec/lib/vcr/util/hooks_spec.rb +0 -158
  123. data/spec/lib/vcr/util/internet_connection_spec.rb +0 -37
  124. data/spec/lib/vcr/util/version_checker_spec.rb +0 -31
  125. data/spec/lib/vcr/version_spec.rb +0 -27
  126. data/spec/lib/vcr_spec.rb +0 -354
  127. data/spec/monkey_patches.rb +0 -186
  128. data/spec/spec_helper.rb +0 -63
  129. data/spec/support/configuration_stubbing.rb +0 -8
  130. data/spec/support/cucumber_helpers.rb +0 -39
  131. data/spec/support/fixnum_extension.rb +0 -10
  132. data/spec/support/http_library_adapters.rb +0 -289
  133. data/spec/support/limited_uri.rb +0 -21
  134. data/spec/support/ruby_interpreter.rb +0 -7
  135. data/spec/support/shared_example_groups/excon.rb +0 -63
  136. data/spec/support/shared_example_groups/hook_into_http_library.rb +0 -594
  137. data/spec/support/shared_example_groups/request_hooks.rb +0 -59
  138. data/spec/support/sinatra_app.rb +0 -86
  139. data/spec/support/vcr_localhost_server.rb +0 -76
  140. data/spec/support/vcr_stub_helpers.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3bd06000e811a9f066f1d73a5d955bbb4ad3733e
4
- data.tar.gz: 2784446a0155cfef8d7389208213b5b86aad1b8e
2
+ SHA256:
3
+ metadata.gz: 79ff7c5f67afb190b63450e117a7dbda6709340fbab8c17680c36b2bb5a8a6f6
4
+ data.tar.gz: a6a17620c6c63d9a596a39e2700f3f1becddb26bfa63f862e42ef0dfabb783d9
5
5
  SHA512:
6
- metadata.gz: cb7de4b059e58371b9669c4bf72c3c5f806594e5f9cbd614ed5e41bbbd40d30f38a2bf5e2e079da0b139989aaca57080134d736f8680ff0344191f47a2ceba45
7
- data.tar.gz: 1cf77c3a9198f1995721acbabd3470f2735d7e682280f218bdc46385342923beb6956080522e37761132f60ea1d4b67e4a5cfac5bd33d6471df22105a60cb766
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
 
@@ -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
- @http_interactions ||= HTTPInteractionList.new \
75
- should_stub_requests? ? previously_recorded_interactions : [],
76
- match_requests_on,
77
- @allow_playback_repeats,
78
- @parent_list,
79
- log_prefix
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
- if index = matching_interaction_index_for(request)
32
- interaction = @interactions.delete_at(index)
33
- @used_interactions.unshift interaction
34
- log "Found matching interaction for #{request_summary(request)} at index #{index}: #{response_summary(interaction.response)}", 1
35
- interaction.response
36
- elsif interaction = matching_used_interaction_for(request)
37
- interaction.response
38
- else
39
- @parent_list.response_for(request)
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(/[^\w\-\/]+/, '_') + file_extension.to_s
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
@@ -17,9 +17,9 @@ module VCR
17
17
 
18
18
  # The file extension to use for this serializer.
19
19
  #
20
- # @return [String] "gz"
20
+ # @return [String] "zz"
21
21
  def file_extension
22
- 'gz'
22
+ 'zz'
23
23
  end
24
24
 
25
25
  # Serializes the given hash using YAML and Zlib.
@@ -1,4 +1,4 @@
1
- require 'multi_json'
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 = [MultiJson::DecodeError, ArgumentError]
17
- ENCODING_ERRORS << EncodingError if defined?(EncodingError)
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 `MultiJson`.
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
- MultiJson.encode(hash)
32
+ ::JSON.generate(hash)
33
33
  end
34
34
  end
35
35
 
36
- # Deserializes the given string using `MultiJson`.
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
- MultiJson.decode(string)
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
 
@@ -54,16 +54,14 @@ module VCR
54
54
  #
55
55
  # @example
56
56
  # VCR.configure do |c|
57
- # c.hook_into :fakeweb, :typhoeus
57
+ # c.hook_into :webmock, :typhoeus
58
58
  # end
59
59
  #
60
60
  # @param hooks [Array<Symbol>] List of libraries. Valid values are
61
- # `:fakeweb`, `:webmock`, `:typhoeus`, `:excon` and `:faraday`.
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 #{placeholder.inspect} with #{orig_text.inspect}"
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 FakeWeb/WebMock/etc itself is not available
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
-
@@ -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