vcr 2.9.3 → 3.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.
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
@@ -81,8 +81,10 @@ module VCR
81
81
 
82
82
  # @private
83
83
  def record_http_interaction(interaction)
84
- log "Recorded HTTP interaction #{request_summary(interaction.request)} => #{response_summary(interaction.response)}"
85
- new_recorded_interactions << interaction
84
+ VCR::CassetteMutex.synchronize do
85
+ log "Recorded HTTP interaction #{request_summary(interaction.request)} => #{response_summary(interaction.response)}"
86
+ new_recorded_interactions << interaction
87
+ end
86
88
  end
87
89
 
88
90
  # @private
@@ -2,10 +2,11 @@ module VCR
2
2
  class Cassette
3
3
  # Keeps track of the cassette serializers in a hash-like object.
4
4
  class Serializers
5
- autoload :YAML, 'vcr/cassette/serializers/yaml'
6
- autoload :Syck, 'vcr/cassette/serializers/syck'
7
- autoload :Psych, 'vcr/cassette/serializers/psych'
8
- autoload :JSON, 'vcr/cassette/serializers/json'
5
+ autoload :YAML, 'vcr/cassette/serializers/yaml'
6
+ autoload :Syck, 'vcr/cassette/serializers/syck'
7
+ autoload :Psych, 'vcr/cassette/serializers/psych'
8
+ autoload :JSON, 'vcr/cassette/serializers/json'
9
+ autoload :Compressed, 'vcr/cassette/serializers/compressed'
9
10
 
10
11
  # @private
11
12
  def initialize
@@ -20,10 +21,11 @@ module VCR
20
21
  def [](name)
21
22
  @serializers.fetch(name) do |_|
22
23
  @serializers[name] = case name
23
- when :yaml then YAML
24
- when :syck then Syck
25
- when :psych then Psych
26
- when :json then JSON
24
+ when :yaml then YAML
25
+ when :syck then Syck
26
+ when :psych then Psych
27
+ when :json then JSON
28
+ when :compressed then Compressed
27
29
  else raise ArgumentError.new("The requested VCR cassette serializer (#{name.inspect}) is not registered.")
28
30
  end
29
31
  end
@@ -0,0 +1,45 @@
1
+ require 'zlib'
2
+ require 'vcr/cassette/serializers'
3
+
4
+ module VCR
5
+ class Cassette
6
+ class Serializers
7
+ # The compressed serializer. This serializer wraps the YAML serializer
8
+ # to write compressed cassettes to disk.
9
+ #
10
+ # Cassettes containing responses with JSON data often compress at greater
11
+ # than 10:1. The tradeoff is that cassettes will not diff nicely or be
12
+ # easily inspectable or editable.
13
+ #
14
+ # @see YAML
15
+ module Compressed
16
+ extend self
17
+
18
+ # The file extension to use for this serializer.
19
+ #
20
+ # @return [String] "gz"
21
+ def file_extension
22
+ 'gz'
23
+ end
24
+
25
+ # Serializes the given hash using YAML and Zlib.
26
+ #
27
+ # @param [Hash] hash the object to serialize
28
+ # @return [String] the compressed cassette data
29
+ def serialize(hash)
30
+ string = VCR::Cassette::Serializers::YAML.serialize(hash)
31
+ Zlib::Deflate.deflate(string)
32
+ end
33
+
34
+ # Deserializes the given compressed cassette data.
35
+ #
36
+ # @param [String] string the compressed YAML cassette data
37
+ # @return [Hash] the deserialized object
38
+ def deserialize(string)
39
+ yaml = Zlib::Inflate.inflate(string)
40
+ VCR::Cassette::Serializers::YAML.deserialize(yaml)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -386,23 +386,23 @@ module VCR
386
386
  # @see #before_http_request
387
387
  # @see #after_http_request
388
388
  def around_http_request(*filters, &block)
389
- require 'fiber'
390
- rescue LoadError
391
- raise Errors::NotSupportedError.new \
392
- "VCR::Configuration#around_http_request requires fibers, " +
393
- "which are not available on your ruby intepreter."
394
- else
389
+ unless VCR.fibers_available?
390
+ raise Errors::NotSupportedError.new \
391
+ "VCR::Configuration#around_http_request requires fibers, " +
392
+ "which are not available on your ruby intepreter."
393
+ end
394
+
395
395
  fibers = {}
396
- hook_allowed, hook_decaration = false, caller.first
396
+ fiber_errors = {}
397
+ hook_allowed, hook_declaration = false, caller.first
397
398
  before_http_request(*filters) do |request|
398
399
  hook_allowed = true
399
- fiber = start_new_fiber_for(request, block)
400
- fibers[Thread.current] = fiber
400
+ start_new_fiber_for(request, fibers, fiber_errors, hook_declaration, block)
401
401
  end
402
402
 
403
403
  after_http_request(lambda { hook_allowed }) do |request, response|
404
404
  fiber = fibers.delete(Thread.current)
405
- resume_fiber(fiber, response, hook_decaration)
405
+ resume_fiber(fiber, fiber_errors, response, hook_declaration)
406
406
  end
407
407
  end
408
408
 
@@ -506,20 +506,41 @@ module VCR
506
506
  raise ArgumentError.new("#{hook.inspect} is not a supported VCR HTTP library hook.")
507
507
  end
508
508
 
509
- def resume_fiber(fiber, response, hook_declaration)
509
+ def resume_fiber(fiber, fiber_errors, response, hook_declaration)
510
+ raise fiber_errors[Thread.current] if fiber_errors[Thread.current]
510
511
  fiber.resume(response)
511
- rescue FiberError
512
+ rescue FiberError => ex
512
513
  raise Errors::AroundHTTPRequestHookError.new \
513
- "Your around_http_request hook declared at #{hook_declaration}" +
514
- " must call #proceed on the yielded request but did not."
514
+ "Your around_http_request hook declared at #{hook_declaration}" \
515
+ " must call #proceed on the yielded request but did not. " \
516
+ "(actual error: #{ex.class}: #{ex.message})"
515
517
  end
516
518
 
517
- def start_new_fiber_for(request, block)
518
- Fiber.new(&block).tap do |fiber|
519
- fiber.resume(Request::FiberAware.new(request))
519
+ def create_fiber_for(fiber_errors, hook_declaration, proc)
520
+ current_thread = Thread.current
521
+ Fiber.new do |*args, &block|
522
+ begin
523
+ # JRuby Fiber runs in a separate thread, so we need to make this Fiber
524
+ # use the context of the calling thread
525
+ VCR.link_context(current_thread, Fiber.current) if RUBY_PLATFORM == 'java'
526
+ proc.call(*args, &block)
527
+ rescue StandardError => ex
528
+ # Fiber errors get swallowed, so we re-raise the error in the parent
529
+ # thread (see resume_fiber)
530
+ fiber_errors[current_thread] = ex
531
+ raise
532
+ ensure
533
+ VCR.unlink_context(Fiber.current) if RUBY_PLATFORM == 'java'
534
+ end
520
535
  end
521
536
  end
522
537
 
538
+ def start_new_fiber_for(request, fibers, fiber_errors, hook_declaration, proc)
539
+ fiber = create_fiber_for(fiber_errors, hook_declaration, proc)
540
+ fibers[Thread.current] = fiber
541
+ fiber.resume(Request::FiberAware.new(request))
542
+ end
543
+
523
544
  def tag_filter_from(tag)
524
545
  return lambda { true } unless tag
525
546
  lambda { |_, cassette| cassette.tags.include?(tag) }
@@ -126,6 +126,7 @@ module VCR
126
126
  end
127
127
  end
128
128
 
129
+ # @private
129
130
  class RecursiveRequestHandler < RequestHandler
130
131
  attr_reader :stubbed_response
131
132
 
@@ -10,7 +10,11 @@ module VCR
10
10
  super.extend BuilderInstanceExtension
11
11
  end
12
12
 
13
- ::Faraday::Builder.extend self
13
+ if defined?(::Faraday::RackBuilder)
14
+ ::Faraday::RackBuilder.extend self
15
+ else
16
+ ::Faraday::Builder.extend self
17
+ end
14
18
  end
15
19
 
16
20
  # @private
@@ -45,7 +45,8 @@ module VCR
45
45
  VCR.library_hooks.exclusive_hook = :faraday
46
46
  super
47
47
  ensure
48
- invoke_after_request_hook(response_for(env)) unless delay_finishing?
48
+ response = defined?(@vcr_response) ? @vcr_response : nil
49
+ invoke_after_request_hook(response) unless delay_finishing?
49
50
  end
50
51
 
51
52
  private
@@ -70,10 +71,7 @@ module VCR
70
71
  end
71
72
  end
72
73
 
73
- def response_for(env)
74
- response = env[:response]
75
- return nil unless response
76
-
74
+ def response_for(response)
77
75
  VCR::Response.new(
78
76
  VCR::ResponseStatus.new(response.status, nil),
79
77
  response.headers,
@@ -83,7 +81,9 @@ module VCR
83
81
  end
84
82
 
85
83
  def on_ignored_request
86
- app.call(env)
84
+ response = app.call(env)
85
+ @vcr_response = response_for(response)
86
+ response
87
87
  end
88
88
 
89
89
  def on_stubbed_by_vcr_request
@@ -91,6 +91,8 @@ module VCR
91
91
  headers.update stubbed_response.headers if stubbed_response.headers
92
92
  env.update :status => stubbed_response.status.code, :body => stubbed_response.body
93
93
 
94
+ @vcr_response = stubbed_response
95
+
94
96
  faraday_response = ::Faraday::Response.new
95
97
  faraday_response.finish(env)
96
98
  env[:response] = faraday_response
@@ -98,9 +100,11 @@ module VCR
98
100
 
99
101
  def on_recordable_request
100
102
  @has_on_complete_hook = true
101
- app.call(env).on_complete do |env|
102
- VCR.record_http_interaction(VCR::HTTPInteraction.new(vcr_request, response_for(env)))
103
- invoke_after_request_hook(response_for(env)) if delay_finishing?
103
+ response = app.call(env)
104
+ response.on_complete do
105
+ @vcr_response = response_for(response)
106
+ VCR.record_http_interaction(VCR::HTTPInteraction.new(vcr_request, @vcr_response))
107
+ invoke_after_request_hook(@vcr_response) if delay_finishing?
104
108
  end
105
109
  end
106
110
 
@@ -40,11 +40,18 @@ module VCR
40
40
  options = original_options.dup
41
41
 
42
42
  cassette_name = if options.delete(:use_scenario_name)
43
- feature = scenario.respond_to?(:scenario_outline) ? scenario.scenario_outline.feature : scenario.feature
44
- name = feature.name.split("\n").first
45
- name << "/#{scenario.scenario_outline.name}" if scenario.respond_to?(:scenario_outline)
46
- name << "/#{scenario.name.split("\n").first}"
47
- name
43
+ if scenario.respond_to?(:outline?) && scenario.outline?
44
+ ScenarioNameBuilder.new(scenario).cassette_name
45
+ elsif scenario.respond_to?(:scenario_outline)
46
+ [ scenario.scenario_outline.feature.name.split("\n").first,
47
+ scenario.scenario_outline.name,
48
+ scenario.name.split("\n").first
49
+ ].join("/")
50
+ else
51
+ [ scenario.feature.name.split("\n").first,
52
+ scenario.name.split("\n").first
53
+ ].join("/")
54
+ end
48
55
  else
49
56
  "cucumber_tags/#{tag_name.gsub(/\A@/, '')}"
50
57
  end
@@ -60,5 +67,32 @@ module VCR
60
67
  end
61
68
  end
62
69
  alias :tag :tags
70
+
71
+ # Constructs a cassette name from a Cucumber 2 scenario outline
72
+ # @private
73
+ class ScenarioNameBuilder
74
+ def initialize(test_case)
75
+ @parts = []
76
+ test_case.describe_source_to self
77
+ end
78
+
79
+ def cassette_name
80
+ @parts.join("/")
81
+ end
82
+
83
+ def feature(feature)
84
+ @parts.unshift feature.name
85
+ self
86
+ end
87
+ alias scenario_outline feature
88
+
89
+ def scenario(*) self end
90
+ alias examples_table scenario
91
+
92
+ def examples_table_row(row)
93
+ @parts.unshift "| %s |" % row.values.join(" | ")
94
+ self
95
+ end
96
+ end
63
97
  end
64
98
  end
@@ -10,7 +10,7 @@ module VCR
10
10
  # * `parts` [Array<Integer>] List of the version parts.
11
11
  def version
12
12
  @version ||= begin
13
- string = '2.9.3'
13
+ string = '3.0.0'
14
14
 
15
15
  def string.parts
16
16
  split('.').map { |p| p.to_i }
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe VCR do
4
+ def recorded_content_for(name)
5
+ VCR.cassette_persisters[:file_system]["#{name}.yml"].to_s
6
+ end
7
+
8
+ context 'when used in a multithreaded environment with an around_http_request', :with_monkey_patches => :excon do
9
+ def preload_yaml_serializer_to_avoid_circular_require_warning_race_condition
10
+ VCR.cassette_serializers[:yaml]
11
+ end
12
+
13
+ before { preload_yaml_serializer_to_avoid_circular_require_warning_race_condition }
14
+
15
+ it 'can use a cassette in an #around_http_request hook', :if => (RUBY_VERSION.to_f > 1.8) do
16
+ VCR.configure do |vcr|
17
+ vcr.around_http_request do |req|
18
+ VCR.use_cassette(req.parsed_uri.path, &req)
19
+ end
20
+ end
21
+
22
+ threads = 50.times.map do
23
+ Thread.start do
24
+ Excon.get "http://localhost:#{VCR::SinatraApp.port}/search?q=thread"
25
+ end
26
+ end
27
+ Excon.get "http://localhost:#{VCR::SinatraApp.port}/foo"
28
+ threads.each(&:join)
29
+
30
+ expect(recorded_content_for("search") +
31
+ recorded_content_for("foo")).to include("query: thread", "FOO!")
32
+ end
33
+ end
34
+
35
+ context 'when used in a multithreaded environment with a cassette', :with_monkey_patches => :excon do
36
+ it 'properly stubs threaded requests' do
37
+ VCR.use_cassette('/foo') do
38
+ threads = 50.times.map do
39
+ Thread.start do
40
+ Excon.get "http://localhost:#{VCR::SinatraApp.port}/foo"
41
+ end
42
+ end
43
+ threads.each(&:join)
44
+ end
45
+
46
+ expect(
47
+ recorded_content_for("foo")).to include("FOO!")
48
+ end
49
+ end
50
+ end
51
+
@@ -1,5 +1,6 @@
1
1
  require 'tmpdir'
2
2
  require 'vcr/cassette/migrator'
3
+ require 'yaml'
3
4
 
4
5
  describe VCR::Cassette::Migrator do
5
6
  let(:original_contents) { <<-EOF
@@ -114,13 +115,14 @@ EOF
114
115
  end if RUBY_PLATFORM == 'java'
115
116
 
116
117
  # Use syck on all rubies for consistent results...
117
- before(:each) do
118
- YAML::ENGINE.yamler = 'syck' if defined?(YAML::ENGINE)
119
- end
120
-
121
- after(:each) do
122
- YAML::ENGINE.yamler = 'psych' if defined?(YAML::ENGINE)
123
- end
118
+ around(:each) do |example|
119
+ YAML::ENGINE.yamler = 'syck'
120
+ begin
121
+ example.call
122
+ ensure
123
+ YAML::ENGINE.yamler = 'psych'
124
+ end
125
+ end if defined?(YAML::ENGINE) && RUBY_VERSION.to_f < 2.0
124
126
 
125
127
  let(:filemtime) { Time.utc(2011, 5, 4, 12, 30) }
126
128
  let(:out_io) { StringIO.new }
@@ -185,11 +187,10 @@ EOF
185
187
 
186
188
  context 'with psych' do
187
189
  before(:each) do
188
- pending "psych not available" unless defined?(YAML::ENGINE)
189
190
  YAML::ENGINE.yamler = 'psych'
190
191
  end
191
192
 
192
193
  it_behaves_like "ignoring invalid YAML"
193
- end
194
+ end if defined?(YAML::ENGINE)
194
195
  end
195
196
 
@@ -50,7 +50,7 @@ module VCR
50
50
  it_behaves_like "a serializer", :yaml, "yml", :lazily_loaded do
51
51
  it_behaves_like "encoding error handling", :yaml, ArgumentError do
52
52
  let(:string) { "\xFA".force_encoding("UTF-8") }
53
- before { ::YAML::ENGINE.yamler = 'psych' }
53
+ before { ::YAML::ENGINE.yamler = 'psych' if defined?(::YAML::ENGINE) }
54
54
  end if ''.respond_to?(:encoding)
55
55
  end
56
56
 
@@ -66,6 +66,12 @@ module VCR
66
66
  end if ''.respond_to?(:encoding)
67
67
  end if RUBY_VERSION =~ /1.9/
68
68
 
69
+ it_behaves_like "a serializer", :compressed, "gz", :lazily_loaded do
70
+ it_behaves_like "encoding error handling", :compressed, ArgumentError do
71
+ let(:string) { "\xFA".force_encoding("UTF-8") }
72
+ end if ''.respond_to?(:encoding)
73
+ end
74
+
69
75
  it_behaves_like "a serializer", :json, "json", :lazily_loaded do
70
76
  engines = {}
71
77
 
@@ -156,7 +162,7 @@ module VCR
156
162
  ::YAML::ENGINE.yamler = 'syck'
157
163
  serialized = subject[:psych].serialize(problematic_syck_string)
158
164
  expect(subject[:psych].deserialize(serialized)).to eq(problematic_syck_string)
159
- end if defined?(::Psych)
165
+ end if defined?(::Psych) && RUBY_VERSION.to_f < 2.0
160
166
 
161
167
  it 'raises an error if psych cannot be loaded' do
162
168
  expect { subject[:psych] }.to raise_error(LoadError)