vcr 2.9.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/features/about_these_examples.md +1 -1
  3. data/features/cassettes/automatic_re_recording.feature +4 -4
  4. data/features/cassettes/decompress.feature +3 -3
  5. data/features/cassettes/exclusive.feature +11 -8
  6. data/features/cassettes/format.feature +135 -32
  7. data/features/cassettes/naming.feature +2 -2
  8. data/features/cassettes/no_cassette.feature +4 -4
  9. data/features/configuration/allow_http_connections_when_no_cassette.feature +6 -3
  10. data/features/configuration/cassette_library_dir.feature +2 -2
  11. data/features/configuration/debug_logging.feature +15 -8
  12. data/features/configuration/filter_sensitive_data.feature +8 -7
  13. data/features/configuration/hook_into.feature +8 -8
  14. data/features/configuration/ignore_request.feature +13 -14
  15. data/features/configuration/preserve_exact_body_bytes.feature +5 -5
  16. data/features/configuration/uri_parser.feature +15 -11
  17. data/features/hooks/after_http_request.feature +5 -4
  18. data/features/hooks/around_http_request.feature +3 -3
  19. data/features/hooks/before_http_request.feature +4 -2
  20. data/features/hooks/before_playback.feature +14 -15
  21. data/features/hooks/before_record.feature +10 -10
  22. data/features/http_libraries/em_http_request.feature +6 -3
  23. data/features/http_libraries/net_http.feature +15 -5
  24. data/features/middleware/faraday.feature +2 -2
  25. data/features/middleware/rack.feature +4 -4
  26. data/features/record_modes/all.feature +5 -5
  27. data/features/record_modes/new_episodes.feature +2 -2
  28. data/features/record_modes/once.feature +3 -3
  29. data/features/step_definitions/cli_steps.rb +37 -39
  30. data/features/support/env.rb +29 -26
  31. data/features/support/http_lib_filters.rb +0 -7
  32. data/features/test_frameworks/cucumber.feature +11 -10
  33. data/features/test_frameworks/rspec_macro.feature +5 -30
  34. data/features/test_frameworks/rspec_metadata.feature +9 -8
  35. data/features/test_frameworks/test_unit.feature +5 -2
  36. data/lib/vcr.rb +86 -14
  37. data/lib/vcr/cassette.rb +4 -2
  38. data/lib/vcr/cassette/serializers.rb +10 -8
  39. data/lib/vcr/cassette/serializers/compressed.rb +45 -0
  40. data/lib/vcr/configuration.rb +38 -17
  41. data/lib/vcr/library_hooks/fakeweb.rb +1 -0
  42. data/lib/vcr/library_hooks/faraday.rb +5 -1
  43. data/lib/vcr/middleware/faraday.rb +13 -9
  44. data/lib/vcr/test_frameworks/cucumber.rb +39 -5
  45. data/lib/vcr/version.rb +1 -1
  46. data/spec/acceptance/concurrency_spec.rb +51 -0
  47. data/spec/{vcr → lib/vcr}/cassette/erb_renderer_spec.rb +0 -0
  48. data/spec/{vcr → lib/vcr}/cassette/http_interaction_list_spec.rb +0 -0
  49. data/spec/{vcr → lib/vcr}/cassette/migrator_spec.rb +10 -9
  50. data/spec/{vcr → lib/vcr}/cassette/persisters/file_system_spec.rb +0 -0
  51. data/spec/{vcr → lib/vcr}/cassette/persisters_spec.rb +0 -0
  52. data/spec/{vcr → lib/vcr}/cassette/serializers_spec.rb +8 -2
  53. data/spec/{vcr → lib/vcr}/cassette_spec.rb +0 -0
  54. data/spec/{vcr → lib/vcr}/configuration_spec.rb +0 -0
  55. data/spec/{vcr → lib/vcr}/deprecations_spec.rb +0 -0
  56. data/spec/{vcr → lib/vcr}/errors_spec.rb +0 -0
  57. data/spec/{vcr → lib/vcr}/extensions/net_http_response_spec.rb +0 -0
  58. data/spec/{vcr → lib/vcr}/library_hooks/excon_spec.rb +0 -0
  59. data/spec/{vcr → lib/vcr}/library_hooks/fakeweb_spec.rb +0 -0
  60. data/spec/{vcr → lib/vcr}/library_hooks/faraday_spec.rb +0 -0
  61. data/spec/{vcr → lib/vcr}/library_hooks/typhoeus_0.4_spec.rb +0 -0
  62. data/spec/{vcr → lib/vcr}/library_hooks/typhoeus_spec.rb +0 -0
  63. data/spec/{vcr → lib/vcr}/library_hooks/webmock_spec.rb +2 -2
  64. data/spec/{vcr → lib/vcr}/library_hooks_spec.rb +0 -0
  65. data/spec/{vcr → lib/vcr}/middleware/faraday_spec.rb +0 -0
  66. data/spec/{vcr → lib/vcr}/middleware/rack_spec.rb +0 -0
  67. data/spec/{vcr → lib/vcr}/request_ignorer_spec.rb +0 -0
  68. data/spec/{vcr → lib/vcr}/request_matcher_registry_spec.rb +0 -0
  69. data/spec/{vcr → lib/vcr}/structs_spec.rb +0 -0
  70. data/spec/{vcr → lib/vcr}/test_frameworks/cucumber_spec.rb +0 -0
  71. data/spec/{vcr → lib/vcr}/test_frameworks/rspec_spec.rb +0 -0
  72. data/spec/{vcr → lib/vcr}/util/hooks_spec.rb +0 -0
  73. data/spec/{vcr → lib/vcr}/util/internet_connection_spec.rb +0 -0
  74. data/spec/{vcr → lib/vcr}/util/version_checker_spec.rb +0 -0
  75. data/spec/{vcr → lib/vcr}/version_spec.rb +0 -0
  76. data/spec/{vcr_spec.rb → lib/vcr_spec.rb} +2 -2
  77. data/spec/spec_helper.rb +21 -50
  78. data/spec/support/cucumber_helpers.rb +39 -0
  79. data/spec/support/limited_uri.rb +1 -11
  80. data/spec/support/shared_example_groups/hook_into_http_library.rb +2 -1
  81. data/spec/support/vcr_localhost_server.rb +2 -3
  82. metadata +475 -123
  83. data/.gemtest +0 -0
  84. data/.gitignore +0 -52
  85. data/.gitmodules +0 -3
  86. data/.rspec +0 -2
  87. data/.travis.yml +0 -27
  88. data/.yardopts +0 -9
  89. data/Appraisals +0 -5
  90. data/CHANGELOG.md +0 -987
  91. data/CONTRIBUTING.md +0 -26
  92. data/Gemfile +0 -54
  93. data/Gemfile.lock +0 -159
  94. data/LICENSE +0 -20
  95. data/README.md +0 -243
  96. data/Rakefile +0 -197
  97. data/Upgrade.md +0 -289
  98. data/benchmarks/http_stubbing_libraries.rb +0 -59
  99. data/benchmarks/null_logging.rb +0 -62
  100. data/cucumber.yml +0 -16
  101. data/features/.nav +0 -62
  102. data/features/cassettes/persistence.feature +0 -63
  103. data/features/support/vcr_cucumber_helpers.rb +0 -46
  104. data/gemfiles/typhoeus_old.gemfile +0 -34
  105. data/gemfiles/typhoeus_old.gemfile.lock +0 -133
  106. data/script/ci.sh +0 -27
  107. data/spec/capture_warnings.rb +0 -73
  108. data/spec/quality_spec.rb +0 -51
  109. data/vcr.gemspec +0 -23
data/Rakefile DELETED
@@ -1,197 +0,0 @@
1
- using_git = File.exist?(File.expand_path('../.git/', __FILE__))
2
-
3
- if using_git
4
- require 'bundler/setup'
5
- require 'bundler/gem_helper'
6
- Bundler::GemHelper.install_tasks
7
- require 'appraisal'
8
- end
9
-
10
- require 'rake'
11
- require "rspec/core/rake_task"
12
-
13
- RSpec::Core::RakeTask.new(:spec) do |t|
14
- t.verbose = false
15
-
16
- # we require spec_helper so we don't get an RSpec warning about
17
- # examples being defined before configuration.
18
- t.ruby_opts = "-I./spec -r./spec/capture_warnings -rspec_helper"
19
- t.rspec_opts = %w[--format progress] if (ENV['FULL_BUILD'] || !using_git)
20
- end
21
-
22
- require 'cucumber/rake/task'
23
- Cucumber::Rake::Task.new
24
-
25
- task :default => [:submodules, :spec, :cucumber]
26
-
27
- desc "Ensures we keep up 100% YARD coverage"
28
- task :yard_coverage do
29
- coverage_stats = `yard stats --list-undoc 2>&1`
30
- puts coverage_stats
31
- if coverage_stats.include?('100.00% documented')
32
- puts "\nNice work! 100% documentation coverage"
33
- else
34
- raise "Documentation coverage is less than 100%"
35
- end
36
- end
37
-
38
- desc "Checks the spec coverage and fails if it is less than 100%"
39
- task :check_code_coverage do
40
- if RUBY_VERSION.to_f < 1.9 || RUBY_ENGINE != 'ruby'
41
- puts "Cannot check code coverage--simplecov is not supported on this platform"
42
- else
43
- percent = File.read("./coverage/coverage_percent.txt").to_f
44
- if percent < 98.0
45
- abort "Spec coverage was not high enough: #{percent.round(2)}%"
46
- else
47
- puts "Nice job! Spec coverage is still above 98%"
48
- end
49
- end
50
- end
51
-
52
- desc "Checkout git submodules"
53
- task :submodules do
54
- sh "git submodule sync"
55
- sh "git submodule update --init --recursive"
56
- end
57
-
58
- namespace :ci do
59
- desc "Sets things up for a ci build on travis-ci.org"
60
- task :setup => :submodules do
61
- ENV['TRAVIS'] = 'true'
62
- end
63
-
64
- RSpec::Core::RakeTask.new(:spec) do |t|
65
- t.verbose = true
66
-
67
- # we require spec_helper so we don't get an RSpec warning about
68
- # examples being defined before configuration.
69
- t.ruby_opts = "-w -I./spec -r./spec/capture_warnings -rspec_helper"
70
- t.rspec_opts = %w[--format progress --backtrace]
71
- end
72
-
73
- desc "Run a ci build"
74
- task :build => [:setup, :spec, :cucumber, :yard_coverage, :check_code_coverage]
75
- end
76
-
77
- def ensure_relish_doc_symlinked(filename)
78
- from_filename = filename.dup
79
- from_filename << '.md' unless filename =~ /\.md$/
80
- from = File.expand_path("../features/#{from_filename}", __FILE__)
81
- to = File.expand_path("../#{filename}", __FILE__)
82
-
83
- if File.symlink?(from)
84
- return if File.readlink(from) == to
85
-
86
- # delete the old symlink
87
- File.unlink(from)
88
- end
89
-
90
- FileUtils.ln_s to, from
91
- end
92
-
93
- desc "Push cukes to relishapp using the relish-client-gem"
94
- task :relish do
95
- unless ENV['SKIP_RELISH']
96
- %w[ README.md CHANGELOG.md Upgrade.md LICENSE CONTRIBUTING.md].each do |file|
97
- ensure_relish_doc_symlinked(file)
98
- end
99
-
100
- require 'vcr/version'
101
- sh "relish versions:add vcr/vcr:#{VCR.version}" if ENV['NEW_RELISH_RELEASE'] == 'true'
102
- sh "relish push vcr/vcr:#{VCR.version}"
103
- end
104
- end
105
-
106
- task :prep_relish_release do
107
- ENV['NEW_RELISH_RELEASE'] ||= 'true'
108
- end
109
-
110
- task :release => [:prep_relish_release, :relish]
111
-
112
- # For gem-test: http://gem-testers.org/
113
- task :test => :spec
114
-
115
- load './lib/vcr/tasks/vcr.rake'
116
- namespace :vcr do
117
- task :reset_spec_cassettes do
118
- ENV['DIR'] = 'spec/fixtures'
119
- def VCR.version; "2.0.0"; end
120
- sh "git checkout v2.0.0.beta1 -- spec/fixtures"
121
- end
122
-
123
- task :migrate_cassettes => :reset_spec_cassettes
124
- end
125
-
126
- desc "Migrate cucumber cassettes"
127
- task :migrate_cucumber_cassettes do
128
- require 'vcr'
129
- require 'ruby-debug'
130
-
131
- VCR.configure do |c|
132
- c.cassette_library_dir = 'tmp/migrate'
133
- c.default_cassette_options = { :serialize_with => :syck }
134
- end
135
-
136
- # We want 2.0.0 in the cucumber cassettes instead of 2.0.0.rc1
137
- def VCR.version
138
- "2.0.0"
139
- end
140
-
141
- Dir["features/**/*.feature"].each do |feature_file|
142
- # The ERB cassettes can't be migrated automatically.
143
- next if feature_file.include?('dynamic_erb')
144
-
145
- puts " - Migrating #{feature_file}"
146
- contents = File.read(feature_file)
147
-
148
- # http://rubular.com/r/gjzkoaYX2O
149
- contents.scan(/:\n^\s+"""\n([\s\S]+?)"""/).each do |captures|
150
- capture = captures.first
151
- indentation = capture[/^ +/]
152
- cassette_yml = capture.gsub(/^#{indentation}/, '')
153
- new_yml = nil
154
-
155
- file_name = "tmp/migrate/cassette.yml"
156
- File.open(file_name, 'w') { |f| f.write(cassette_yml) }
157
- cassette = VCR::Cassette.new('cassette')
158
-
159
- hash = begin
160
- cassette.serializable_hash
161
- rescue => e
162
- puts " Skipping #{capture[0, 80]}"
163
- next
164
- end
165
-
166
- new_yml = VCR::Cassette::Serializers::Syck.serialize(hash)
167
-
168
- new_yml.gsub!(/^/, indentation)
169
- new_yml << indentation
170
- new_yml.gsub!(/^\s+\n(\s+response:)/, '\1')
171
- contents.gsub!(capture, new_yml)
172
- end
173
-
174
- File.open(feature_file, 'w') { |f| f.write(contents) }
175
- end
176
- end
177
-
178
- desc "Run the last cuke directly"
179
- task :run_last_cuke do
180
- command = ENV.fetch('CMD') do
181
- raise "Must pass CMD"
182
- end
183
-
184
- Dir.chdir("tmp/aruba") do
185
- sh "RUBYOPT='-I.:../../lib -r../../features/support/vcr_cucumber_helpers' ruby #{command}"
186
- end
187
- end
188
-
189
- desc "Boot test app"
190
- task :boot_test_app do
191
- require './spec/support/vcr_localhost_server'
192
- require './spec/support/sinatra_app'
193
- VCR::SinatraApp.boot
194
- puts "Booted sinatra app on port: #{VCR::SinatraApp.port}"
195
- loop { }
196
- puts "Shutting down."
197
- end
data/Upgrade.md DELETED
@@ -1,289 +0,0 @@
1
- See the [Changelog](changelog) for a complete list of changes from VCR
2
- 1.x to 2.0. This file simply lists the most pertinent ones to upgrading.
3
-
4
- ## Supported Rubies
5
-
6
- Ruby 1.8.6 and 1.9.1 are no longer supported.
7
-
8
- ## Configuration Changes
9
-
10
- In VCR 1.x, your configuration block would be something like this:
11
-
12
- ``` ruby
13
- VCR.config do |c|
14
- c.cassette_library_dir = 'cassettes'
15
- c.stub_with :fakeweb, :typhoeus
16
- end
17
- ```
18
-
19
- This will continue to work in VCR 2.0 but will generate deprecation
20
- warnings. Instead, you should change this to:
21
-
22
- ``` ruby
23
- VCR.configure do |c|
24
- c.cassette_library_dir = 'cassettes'
25
- c.hook_into :fakeweb, :typhoeus
26
- end
27
- ```
28
-
29
- ## New Cassette Format
30
-
31
- The cassette format has changed between VCR 1.x and VCR 2.0.
32
- VCR 1.x cassettes cannot be used with VCR 2.0.
33
-
34
- The easiest way to upgrade is to simply delete your cassettes and
35
- re-record all of them. VCR also provides a rake task that attempts
36
- to upgrade your 1.x cassettes to the new 2.0 format. To use it, add
37
- the following line to your Rakefile:
38
-
39
- ``` ruby
40
- load 'vcr/tasks/vcr.rake'
41
- ```
42
-
43
- Then run `rake vcr:migrate_cassettes DIR=path/to/your/cassettes/directory` to
44
- upgrade your cassettes. Note that this rake task may be unable to
45
- upgrade some cassettes that make extensive use of ERB. In addition, now
46
- that VCR 2.0 does less normalization then before, it may not be able to
47
- migrate the cassette perfectly. It's recommended that you delete and
48
- re-record your cassettes if you are able.
49
-
50
- ## Custom Request Matchers
51
-
52
- VCR 2.0 allows you to register custom request matchers:
53
-
54
- ``` ruby
55
- VCR.configure do |c|
56
- c.register_request_matcher :port do |request_1, request_2|
57
- URI(request_1.uri).port == URI(request_2.uri).port
58
- end
59
- end
60
- ```
61
-
62
- You can also pass any callable (an object that responds to #call, such as a lambda)
63
- to the `:match_requests_on` option:
64
-
65
- ``` ruby
66
- port_matcher = lambda do |request_1, request_2|
67
- URI(request_1.uri).port == URI(request_2.uri).port
68
- end
69
-
70
- VCR.use_cassette("example", :match_requests_on => [:host, port_matcher, :method]) do
71
- # make an HTTP request
72
- end
73
- ```
74
-
75
- In addition, a helper method is provided for generating a custom
76
- matcher that ignores one or more query parameters:
77
-
78
- ``` ruby
79
- uri_without_timestamp = VCR.request_matchers.uri_without_param(:timestamp)
80
- VCR.configure do |c|
81
- c.register_request_matcher(:uri_without_timestamp, &uri_without_timestamp)
82
- end
83
- ```
84
-
85
- ## Custom Serializers
86
-
87
- VCR 2.0 supports multiple serializers. `:yaml`, `:json`, `:psych` and
88
- `:syck` are supported out of the box, and it's easy to implement your
89
- own. Custom serializers must implement `#file_extension`, `#serialize`
90
- and `#deserialize`:
91
-
92
- ``` ruby
93
- VCR.use_cassette("example", :serialize_with => :json) do
94
- # make an HTTP request
95
- end
96
-
97
- marshal_serializer = Object.new
98
- marshal_serializer.instance_eval do
99
- def file_extension
100
- "marsh"
101
- end
102
-
103
- def serialize(hash)
104
- Marshal.dump(hash)
105
- end
106
-
107
- def deserialize(string)
108
- Marshal.load(string)
109
- end
110
- end
111
-
112
- VCR.configure do |c|
113
- c.cassette_serializers[:marshal] = serializer
114
- c.default_cassette_options = { :serialize_with => :marshal }
115
- end
116
- ```
117
-
118
- ## Request Hooks
119
-
120
- VCR 2.0 has new request hooks, allowing you to inject custom logic
121
- before an HTTP request, after an HTTP request, or around an HTTP
122
- request:
123
-
124
- ``` ruby
125
- VCR.configure do |c|
126
- c.before_http_request do |request|
127
- # do something with the request
128
- end
129
-
130
- c.after_http_request do |request, response|
131
- # do something with the request or response
132
- end
133
-
134
- # around_http_request only works on ruby 1.9
135
- c.around_http_request do |request|
136
- uri = URI(request.uri)
137
- if uri.host == 'api.geocoder.com'
138
- # extract an address like "1700 E Pine St, Seattle, WA"
139
- # from a query like "address=1700+E+Pine+St%2C+Seattle%2C+WA"
140
- address = CGI.unescape(uri.query.split('=').last)
141
- VCR.use_cassette("geocoding/#{address}", &request)
142
- else
143
- request.proceed
144
- end
145
- end
146
- end
147
- ```
148
-
149
- ## Ignore a Request Based on Anything
150
-
151
- You can now define what requests get ignored using a block. This
152
- gives you the flexibility to ignore a requets based on anything.
153
-
154
- ``` ruby
155
- VCR.configure do |c|
156
- c.ignore_request do |request|
157
- uri = URI(request.uri)
158
- uri.host == 'localhost' && uri.port == 7500
159
- end
160
- end
161
- ```
162
-
163
- ## Integration with RSpec 2 Metadata
164
-
165
- VCR can integrate directly with RSpec metadata:
166
-
167
- ``` ruby
168
- VCR.configure do |c|
169
- c.configure_rspec_metadata!
170
- end
171
-
172
- RSpec.configure do |c|
173
- # so we can use `:vcr` rather than `:vcr => true`;
174
- # in RSpec 3 this will no longer be necessary.
175
- c.treat_symbols_as_metadata_keys_with_true_values = true
176
- end
177
-
178
- # apply it to an example group
179
- describe MyAPIWrapper, :vcr do
180
- end
181
-
182
- describe MyAPIWrapper do
183
- # apply it to an individual example
184
- it "does something", :vcr do
185
- end
186
-
187
- # set some cassette options
188
- it "does something", :vcr => { :record => :new_episodes } do
189
- end
190
-
191
- # override the cassette name
192
- it "does something", :vcr => { :cassette_name => "something" } do
193
- end
194
- end
195
- ```
196
-
197
- ## Improved Faraday Integration
198
-
199
- VCR 1.x integrated with Faraday but required that you insert
200
- `VCR::Middleware::Faraday` into your middleware stack and configure
201
- `stub_with :faraday`. VCR 2 now takes care of inserting itself
202
- into the Faraday middleware stack if you configure `hook_into :faraday`.
203
-
204
- ## Improved Unhandled Error Messages
205
-
206
- When VCR is unsure how to handle a request, the error message now contains
207
- suggestions for how you can configure VCR or your test so it can handle
208
- the request.
209
-
210
- ## Debug Logger
211
-
212
- VCR 2.0 has a new configuration option that will turn on a logging mode
213
- so you can get more insight into what VCR is doing, for troubleshooting
214
- purposes:
215
-
216
- ``` ruby
217
- VCR.configure do |c|
218
- c.debug_logger = File.open('log/vcr.log')
219
- # or...
220
- c.debug_logger = $stderr
221
- end
222
- ```
223
-
224
- ## Playback Changes
225
-
226
- In VCR 1.x, a single HTTP interaction could be played back multiple
227
- times. This was mostly due to how VCR was implemented using FakeWeb
228
- and WebMock, and was not really by design. It's more in keeping with
229
- the philosophy of VCR to record the entire sequence of HTTP interactions
230
- (including the duplicate requests). In VCR 2, each recorded HTTP
231
- interaction can only be played back once unless you use the new
232
- `:allow_playback_repeats` option.
233
-
234
- In VCR 1.x, request matching was delegated to the HTTP stubbing library
235
- (typically FakeWeb or WebMock). They contain some normalization logic
236
- that can treat some URIs that are different strings as equivalent.
237
- For example, WebMock ignores the ordering of query parameters:
238
-
239
- ``` ruby
240
- > require 'webmock'
241
- => true
242
- > uri1 = "http://foo.com/bar?a=1&b=2"
243
- => "http://foo.com/bar?a=1&b=2"
244
- > uri2 = "http://foo.com/bar?b=2&a=1"
245
- => "http://foo.com/bar?b=2&a=1"
246
- > uri1 == uri2
247
- => false
248
- > WebMock::Util::URI.normalize_uri(uri1) == WebMock::Util::URI.normalize_uri(uri2)
249
- => true
250
- ```
251
-
252
- VCR 2, the `:uri` matcher simply [uses string
253
- equality](https://github.com/myronmarston/vcr/blob/v2.0.0/lib/vcr/request_matcher_registry.rb#L111).
254
- This means that there are some cases of non-deterministic URIs that VCR
255
- 1.x matched but VCR 2.0 will not match. If you need the `:uri` matcher
256
- to be tolerant of slight variations like these, you can easily override
257
- it:
258
-
259
- ``` ruby
260
- VCR.configure do |c|
261
- c.register_request_matcher(:uri) do |r1, r2|
262
- WebMock::Util::URI.normalize_uri(r1.uri) == WebMock::Util::URI.normalize_uri(r2.uri)
263
- end
264
- end
265
- ```
266
-
267
- ## Preserve Exact Body Bytes
268
-
269
- Sometimes the request or response body of an HTTP interaction cannot
270
- be serialized and deserialized properly. Usually this is due to the body
271
- having invalid UTF-8 bytes. This new option configures VCR to base64
272
- encode the body in order to preserve the bytes exactly. It can either
273
- be configured globally with a block, or set on individual cassettes:
274
-
275
- ``` ruby
276
- VCR.configure do |c|
277
- c.preserve_exact_body_bytes do |http_message|
278
- http_message.body.encoding.name == 'ASCII-8BIT' ||
279
- !http_message.body.valid_encoding?
280
- end
281
- end
282
-
283
- # or....
284
-
285
- VCR.use_cassette("my_cassette", :preserve_exact_body_bytes => true) do
286
- # ...
287
- end
288
- ```
289
-