vcr 1.4.0 → 1.5.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 (79) hide show
  1. data/CHANGELOG.md +23 -0
  2. data/Gemfile +0 -2
  3. data/Gemfile.lock +15 -14
  4. data/Guardfile +2 -3
  5. data/LICENSE +1 -1
  6. data/README.md +5 -1
  7. data/features/.nav +28 -0
  8. data/features/README.md +1 -1
  9. data/features/cassettes/automatic_re_recording.feature +2 -2
  10. data/features/cassettes/format.feature +2 -2
  11. data/features/cassettes/no_cassette.feature +3 -3
  12. data/features/cassettes/request_matching.feature +8 -8
  13. data/features/configuration/allow_http_connections_when_no_cassette.feature +1 -1
  14. data/features/configuration/cassette_library_dir.feature +1 -1
  15. data/features/configuration/default_cassette_options.feature +2 -2
  16. data/features/configuration/hooks.feature +276 -0
  17. data/features/configuration/ignore_localhost.feature +1 -1
  18. data/features/configuration/stub_with.feature +19 -20
  19. data/features/middleware/rack.feature +6 -6
  20. data/features/{cassettes/record_modes → record_modes}/all.feature +2 -2
  21. data/features/{cassettes/record_modes → record_modes}/new_episodes.feature +3 -3
  22. data/features/{cassettes/record_modes → record_modes}/none.feature +4 -4
  23. data/features/support/vcr_cucumber_helpers.rb +1 -1
  24. data/features/test_frameworks/cucumber.feature +11 -11
  25. data/features/test_frameworks/rspec.feature +12 -12
  26. data/features/test_frameworks/shoulda.feature +1 -1
  27. data/lib/vcr.rb +8 -4
  28. data/lib/vcr/cassette.rb +28 -39
  29. data/lib/vcr/cassette/reader.rb +58 -0
  30. data/lib/vcr/config.rb +45 -40
  31. data/lib/vcr/deprecations.rb +1 -1
  32. data/lib/vcr/extensions/net_http.rb +6 -1
  33. data/lib/vcr/hooks.rb +45 -0
  34. data/lib/vcr/http_stubbing_adapters/common.rb +16 -13
  35. data/lib/vcr/http_stubbing_adapters/fakeweb.rb +4 -4
  36. data/lib/vcr/http_stubbing_adapters/faraday.rb +4 -4
  37. data/lib/vcr/http_stubbing_adapters/typhoeus.rb +4 -4
  38. data/lib/vcr/http_stubbing_adapters/webmock.rb +4 -4
  39. data/lib/vcr/structs.rb +8 -0
  40. data/lib/vcr/{basic_object.rb → util/basic_object.rb} +0 -0
  41. data/lib/vcr/{internet_connection.rb → util/internet_connection.rb} +1 -1
  42. data/lib/vcr/{ping.rb → util/ping.rb} +0 -0
  43. data/lib/vcr/version.rb +1 -1
  44. data/script/FullBuildRakeFile +6 -0
  45. data/script/full_build +1 -1
  46. data/script/spec +1 -0
  47. data/spec/fixtures/1.9.1/cassette_spec/empty.yml +0 -0
  48. data/spec/fixtures/not_1.9.1/cassette_spec/empty.yml +0 -0
  49. data/spec/spec_helper.rb +7 -4
  50. data/spec/support/http_library_adapters.rb +8 -0
  51. data/spec/support/http_stubbing_adapter.rb +2 -2
  52. data/spec/vcr/cassette/reader_spec.rb +59 -0
  53. data/spec/{cassette_spec.rb → vcr/cassette_spec.rb} +115 -54
  54. data/spec/{config_spec.rb → vcr/config_spec.rb} +0 -0
  55. data/spec/{cucumber_tags_spec.rb → vcr/cucumber_tags_spec.rb} +0 -0
  56. data/spec/{deprecations_spec.rb → vcr/deprecations_spec.rb} +0 -0
  57. data/spec/{extensions → vcr/extensions}/net_http_response_spec.rb +0 -0
  58. data/spec/{extensions → vcr/extensions}/net_http_spec.rb +0 -0
  59. data/spec/vcr/hooks_spec.rb +95 -0
  60. data/spec/{http_stubbing_adapters → vcr/http_stubbing_adapters}/fakeweb_spec.rb +0 -0
  61. data/spec/{http_stubbing_adapters → vcr/http_stubbing_adapters}/faraday_spec.rb +5 -3
  62. data/spec/{http_stubbing_adapters → vcr/http_stubbing_adapters}/multi_object_proxy_spec.rb +0 -0
  63. data/spec/{http_stubbing_adapters → vcr/http_stubbing_adapters}/typhoeus_spec.rb +0 -0
  64. data/spec/{http_stubbing_adapters → vcr/http_stubbing_adapters}/webmock_spec.rb +0 -0
  65. data/spec/{middleware → vcr/middleware}/cassette_arguments_spec.rb +0 -0
  66. data/spec/{middleware → vcr/middleware}/faraday_spec.rb +0 -0
  67. data/spec/{middleware → vcr/middleware}/rack_spec.rb +0 -0
  68. data/spec/{request_matcher_spec.rb → vcr/request_matcher_spec.rb} +0 -0
  69. data/spec/{rspec_spec.rb → vcr/rspec_spec.rb} +0 -0
  70. data/spec/{structs_spec.rb → vcr/structs_spec.rb} +15 -4
  71. data/spec/{internet_connection_spec.rb → vcr/util/internet_connection_spec.rb} +0 -0
  72. data/spec/{version_spec.rb → vcr/version_spec.rb} +0 -0
  73. data/spec/vcr_spec.rb +10 -3
  74. data/vcr.gemspec +3 -3
  75. metadata +123 -101
  76. data/spec/fixtures/1.9.1/cassette_spec/erb_with_no_vars.yml +0 -32
  77. data/spec/fixtures/1.9.1/cassette_spec/erb_with_vars.yml +0 -32
  78. data/spec/fixtures/not_1.9.1/cassette_spec/erb_with_no_vars.yml +0 -32
  79. data/spec/fixtures/not_1.9.1/cassette_spec/erb_with_vars.yml +0 -32
@@ -1,5 +1,5 @@
1
1
  module VCR
2
- class Config
2
+ module Config
3
3
  class << self
4
4
  def http_stubbing_library
5
5
  warn "WARNING: `VCR::Config.http_stubbing_library` is deprecated. Use `VCR::Config.http_stubbing_libraries` instead."
@@ -11,7 +11,12 @@ module Net
11
11
  vcr_request = VCR::Request.from_net_http_request(self, request)
12
12
  response = request_without_vcr(request, body)
13
13
 
14
- match_attributes = (cass = VCR.current_cassette) ? cass.match_requests_on : VCR::RequestMatcher::DEFAULT_MATCH_ATTRIBUTES
14
+ match_attributes = if cass = VCR.current_cassette
15
+ cass.match_requests_on
16
+ else
17
+ VCR::RequestMatcher::DEFAULT_MATCH_ATTRIBUTES
18
+ end
19
+
15
20
  if started? && !VCR.http_stubbing_adapter.request_stubbed?(vcr_request, match_attributes)
16
21
  VCR.record_http_interaction VCR::HTTPInteraction.new(vcr_request, VCR::Response.from_net_http_response(response))
17
22
  response.extend VCR::Net::HTTPResponse # "unwind" the response
data/lib/vcr/hooks.rb ADDED
@@ -0,0 +1,45 @@
1
+ module VCR
2
+ module Hooks
3
+ def invoke_hook(hook, tag, *args)
4
+ hooks_for(hook, tag).each do |callback|
5
+ callback.call(*args_for_callback(args, callback))
6
+ end
7
+ end
8
+
9
+ def clear_hooks
10
+ hooks.clear
11
+ end
12
+
13
+ private
14
+
15
+ def hooks
16
+ @hooks ||= Hash.new do |hook_type_hash, hook_type|
17
+ hook_type_hash[hook_type] = Hash.new do |tag_hash, tag|
18
+ tag_hash[tag] = []
19
+ end
20
+ end
21
+ end
22
+
23
+ def define_hook(hook)
24
+ # We must use string eval so that the dynamically
25
+ # defined method can accept a block.
26
+ instance_eval <<-RUBY, __FILE__, __LINE__ + 1
27
+ def #{hook}(tag = nil, &block)
28
+ hooks[#{hook.inspect}][tag] << block
29
+ end
30
+ RUBY
31
+ end
32
+
33
+ def hooks_for(hook, tag)
34
+ for_hook = hooks[hook]
35
+ hooks = for_hook[tag] # matching tagged hooks
36
+ hooks += for_hook[nil] unless tag.nil? # untagged hooks
37
+ hooks
38
+ end
39
+
40
+ def args_for_callback(args, callback)
41
+ return args if callback.arity < 0
42
+ args.first([args.size, callback.arity].min)
43
+ end
44
+ end
45
+ end
@@ -47,12 +47,11 @@ module VCR
47
47
  end
48
48
 
49
49
  def check_version!
50
- version_too_low, version_too_high = compare_version
51
-
52
- if version_too_low
53
- raise "You are using #{library_name} #{version}. VCR requires version #{version_requirement}."
54
- elsif version_too_high
55
- warn "You are using #{library_name} #{version}. VCR is known to work with #{library_name} #{version_requirement}. It may not work with this version."
50
+ case compare_version
51
+ when :too_low
52
+ raise "You are using #{library_name} #{version}. VCR requires version #{version_requirement}."
53
+ when :too_high
54
+ warn "You are using #{library_name} #{version}. VCR is known to work with #{library_name} #{version_requirement}. It may not work with this version."
56
55
  end
57
56
  end
58
57
 
@@ -64,6 +63,10 @@ module VCR
64
63
  self.http_connections_allowed = VCR::Config.allow_http_connections_when_no_cassette?
65
64
  end
66
65
 
66
+ def restore_stubs_checkpoint(cassette)
67
+ raise ArgumentError.new("No checkpoint for #{cassette.inspect} could be found")
68
+ end
69
+
67
70
  private
68
71
 
69
72
  def compare_version
@@ -71,13 +74,13 @@ module VCR
71
74
  min_major, min_minor, min_patch = parse_version(self::MINIMUM_VERSION)
72
75
  max_major, max_minor = parse_version(self::MAXIMUM_VERSION)
73
76
 
74
- return true, false if major < min_major
75
- return false, true if major > max_major
76
-
77
- return true, false if minor < min_minor
78
- return false, true if minor > max_minor
79
-
80
- return patch < min_patch, false
77
+ case
78
+ when major < min_major; :too_low
79
+ when major > max_major; :too_high
80
+ when minor < min_minor; :too_low
81
+ when minor > max_minor; :too_high
82
+ when patch < min_patch; :too_low
83
+ end
81
84
  end
82
85
 
83
86
  def version_requirement
@@ -43,12 +43,12 @@ module VCR
43
43
  end
44
44
  end
45
45
 
46
- def create_stubs_checkpoint(checkpoint_name)
47
- checkpoints[checkpoint_name] = ::FakeWeb::Registry.instance.uri_map.dup
46
+ def create_stubs_checkpoint(cassette)
47
+ checkpoints[cassette] = ::FakeWeb::Registry.instance.uri_map.dup
48
48
  end
49
49
 
50
- def restore_stubs_checkpoint(checkpoint_name)
51
- ::FakeWeb::Registry.instance.uri_map = checkpoints.delete(checkpoint_name)
50
+ def restore_stubs_checkpoint(cassette)
51
+ ::FakeWeb::Registry.instance.uri_map = checkpoints.delete(cassette) || super
52
52
  end
53
53
 
54
54
  def request_stubbed?(request, match_attributes)
@@ -26,12 +26,12 @@ module VCR
26
26
  end
27
27
  end
28
28
 
29
- def create_stubs_checkpoint(checkpoint_name)
30
- checkpoints[checkpoint_name] = stub_queue_dup
29
+ def create_stubs_checkpoint(cassette)
30
+ checkpoints[cassette] = stub_queue_dup
31
31
  end
32
32
 
33
- def restore_stubs_checkpoint(checkpoint_name)
34
- @stub_queues = checkpoints.delete(checkpoint_name)
33
+ def restore_stubs_checkpoint(cassette)
34
+ @stub_queues = checkpoints.delete(cassette) || super
35
35
  end
36
36
 
37
37
  def stubbed_response_for(request_matcher)
@@ -43,12 +43,12 @@ module VCR
43
43
  end
44
44
  end
45
45
 
46
- def create_stubs_checkpoint(checkpoint_name)
47
- checkpoints[checkpoint_name] = ::Typhoeus::Hydra.stubs.dup
46
+ def create_stubs_checkpoint(cassette)
47
+ checkpoints[cassette] = ::Typhoeus::Hydra.stubs.dup
48
48
  end
49
49
 
50
- def restore_stubs_checkpoint(checkpoint_name)
51
- ::Typhoeus::Hydra.stubs = checkpoints.delete(checkpoint_name)
50
+ def restore_stubs_checkpoint(cassette)
51
+ ::Typhoeus::Hydra.stubs = checkpoints.delete(cassette) || super
52
52
  end
53
53
 
54
54
  private
@@ -36,12 +36,12 @@ module VCR
36
36
  end
37
37
  end
38
38
 
39
- def create_stubs_checkpoint(checkpoint_name)
40
- checkpoints[checkpoint_name] = ::WebMock::StubRegistry.instance.request_stubs.dup
39
+ def create_stubs_checkpoint(cassette)
40
+ checkpoints[cassette] = ::WebMock::StubRegistry.instance.request_stubs.dup
41
41
  end
42
42
 
43
- def restore_stubs_checkpoint(checkpoint_name)
44
- ::WebMock::StubRegistry.instance.request_stubs = checkpoints.delete(checkpoint_name)
43
+ def restore_stubs_checkpoint(cassette)
44
+ ::WebMock::StubRegistry.instance.request_stubs = checkpoints.delete(cassette) || super
45
45
  end
46
46
 
47
47
  private
data/lib/vcr/structs.rb CHANGED
@@ -157,5 +157,13 @@ module VCR
157
157
  class HTTPInteraction < Struct.new(:request, :response)
158
158
  extend ::Forwardable
159
159
  def_delegators :request, :uri, :method
160
+
161
+ def ignore!
162
+ @ignored = true
163
+ end
164
+
165
+ def ignored?
166
+ @ignored
167
+ end
160
168
  end
161
169
  end
File without changes
@@ -1,4 +1,4 @@
1
- require 'vcr/ping'
1
+ require 'vcr/util/ping'
2
2
 
3
3
  module VCR
4
4
  module InternetConnection
File without changes
data/lib/vcr/version.rb CHANGED
@@ -3,7 +3,7 @@ module VCR
3
3
 
4
4
  def version
5
5
  @version ||= begin
6
- string = '1.4.0'
6
+ string = '1.5.0'
7
7
 
8
8
  def string.parts; VCR.version.split('.').map { |p| p.to_i }; end
9
9
  def string.major; parts[0]; end
@@ -7,6 +7,12 @@ task :build => :ensure_bundler_installed do
7
7
  sh "rake"
8
8
  end
9
9
 
10
+ desc "Install necessary gems with bundler, runs specs, run cukes"
11
+ task :spec => :ensure_bundler_installed do
12
+ sh "bundle install"
13
+ sh "rake spec"
14
+ end
15
+
10
16
  task :ensure_bundler_installed do
11
17
  installed = begin
12
18
  require 'rubygems'
data/script/full_build CHANGED
@@ -1 +1 @@
1
- rvm 1.8.6,1.8.7,1.9.1,1.9.2,ree,jruby,rbx rake -f script/FullBuildRakeFile build | tee tmp/full_build.out
1
+ rvm 1.8.6,1.8.7,1.9.1,1.9.2,ree,rbx rake -f script/FullBuildRakeFile build && rvm use jruby && bundle install && rake | tee tmp/full_build.out
data/script/spec ADDED
@@ -0,0 +1 @@
1
+ rvm 1.8.6,1.8.7,1.9.1,1.9.2,ree,rbx rake -f script/FullBuildRakeFile spec && rvm use jruby && bundle install && rake spec | tee tmp/spec.out
File without changes
File without changes
data/spec/spec_helper.rb CHANGED
@@ -7,13 +7,15 @@ require 'rspec'
7
7
  # Ruby 1.9.1 has a different yaml serialization format.
8
8
  YAML_SERIALIZATION_VERSION = RUBY_VERSION == '1.9.1' ? '1.9.1' : 'not_1.9.1'
9
9
 
10
- # Requires supporting files with custom matchers and macros, etc,
11
- # in ./support/ and its subdirectories.
12
- Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require File.join("support", File.basename(f))}
10
+ Dir['./spec/support/**/*.rb'].each { |f| require f }
13
11
 
14
12
  require 'vcr'
15
13
  require 'monkey_patches'
16
14
 
15
+ module VCR
16
+ SPEC_ROOT = File.dirname(__FILE__)
17
+ end
18
+
17
19
  RSpec.configure do |config|
18
20
  config.extend TempCassetteLibraryDir
19
21
  config.extend DisableWarnings
@@ -21,7 +23,7 @@ RSpec.configure do |config|
21
23
  config.extend WebMockMacros
22
24
 
23
25
  config.color_enabled = true
24
- config.debug = RUBY_INTERPRETER == :mri
26
+ config.debug = RUBY_INTERPRETER == :mri && RUBY_VERSION != '1.9.2'
25
27
 
26
28
  config.before(:each) do
27
29
  VCR.turn_on! unless VCR.turned_on?
@@ -29,6 +31,7 @@ RSpec.configure do |config|
29
31
 
30
32
  VCR::Config.default_cassette_options = { :record => :new_episodes }
31
33
  VCR::Config.stub_with :fakeweb
34
+ VCR::Config.clear_hooks
32
35
 
33
36
  WebMock.allow_net_connect!
34
37
  WebMock.reset!
@@ -331,6 +331,14 @@ module HttpLibrarySpecs
331
331
  subject.http_connections_allowed?.should == false
332
332
  end
333
333
 
334
+ describe '.restore_stubs_checkpoint' do
335
+ it 'raises an appropriate error when there is no matching checkpoint' do
336
+ expect {
337
+ subject.restore_stubs_checkpoint(:some_crazy_checkpoint_that_doesnt_exist)
338
+ }.to raise_error(ArgumentError, /no checkpoint .* could be found/i)
339
+ end
340
+ end
341
+
334
342
  [true, false].each do |http_allowed|
335
343
  context "when #http_connections_allowed is set to #{http_allowed}" do
336
344
  before(:each) { subject.http_connections_allowed = http_allowed }
@@ -52,9 +52,9 @@ shared_examples_for "an http stubbing adapter" do |supported_http_libraries, sup
52
52
  end
53
53
 
54
54
  it 're-enables all adapters afterwards' do
55
- VCR::HttpStubbingAdapters::Common.adapters.all? { |a| a.should be_enabled }
55
+ VCR::HttpStubbingAdapters::Common.adapters.each { |a| a.should be_enabled }
56
56
  subject.exclusively_enabled { }
57
- VCR::HttpStubbingAdapters::Common.adapters.all? { |a| a.should be_enabled }
57
+ VCR::HttpStubbingAdapters::Common.adapters.each { |a| a.should be_enabled }
58
58
  end
59
59
  end
60
60
 
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe VCR::Cassette::Reader do
4
+ describe '#read' do
5
+ def read(*args)
6
+ described_class.new(*args).read
7
+ end
8
+
9
+ let(:no_vars_content) { '<%= 3 + 4 %>. Some ERB' }
10
+ let(:vars_content) { '<%= var1 %>. ERB with Vars! <%= var2 %>' }
11
+
12
+ before(:each) do
13
+ File.stub(:read) do |name|
14
+ case name
15
+ when 'no_vars'; no_vars_content
16
+ when 'vars'; vars_content
17
+ else raise ArgumentError.new("Unexpected file name: #{name}")
18
+ end
19
+ end
20
+ end
21
+
22
+ context 'when ERB is disabled' do
23
+ it 'reads the raw file content' do
24
+ read('no_vars', false).should == no_vars_content
25
+ read('no_vars', nil).should == no_vars_content
26
+ end
27
+ end
28
+
29
+ context 'when ERB is enabled but no variables are passed' do
30
+ it 'renders the file content as ERB' do
31
+ read('no_vars', true).should == "7. Some ERB"
32
+ end
33
+
34
+ it 'raises an appropriate error when the ERB template needs variables' do
35
+ expect {
36
+ read('vars', true)
37
+ }.to raise_error(VCR::Cassette::MissingERBVariableError,
38
+ %{The ERB in the vars cassette file references undefined variable var1. } +
39
+ %{Pass it to the cassette using :erb => #{ {:var1=>"some value"}.inspect }.}
40
+ )
41
+ end
42
+ end
43
+
44
+ context 'when ERB is enabled and variables are passed' do
45
+ it 'renders the file content as ERB with the passed variables' do
46
+ read('vars', :var1 => 'foo', :var2 => 'bar').should == 'foo. ERB with Vars! bar'
47
+ end
48
+
49
+ it 'raises an appropriate error when one or more of the needed variables are not passed' do
50
+ expect {
51
+ read('vars', :var1 => 'foo')
52
+ }.to raise_error(VCR::Cassette::MissingERBVariableError,
53
+ %{The ERB in the vars cassette file references undefined variable var2. } +
54
+ %{Pass it to the cassette using :erb => #{ {:var1 => "foo", :var2 => "some value"}.inspect }.}
55
+ )
56
+ end
57
+ end
58
+ end
59
+ end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe VCR::Cassette do
4
4
  describe '#file' do
5
- temp_dir File.expand_path(File.dirname(__FILE__) + '/fixtures/file'), :assign_to_cassette_library_dir => true
5
+ temp_dir "#{VCR::SPEC_ROOT}/fixtures/file", :assign_to_cassette_library_dir => true
6
6
 
7
7
  it 'combines the cassette_library_dir with the cassette name' do
8
8
  cassette = VCR::Cassette.new('the_file')
@@ -51,7 +51,7 @@ describe VCR::Cassette do
51
51
 
52
52
  describe 'on creation' do
53
53
  it 'raises an error with a helpful message when loading an old unsupported cassette' do
54
- VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}")
54
+ VCR::Config.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/#{YAML_SERIALIZATION_VERSION}"
55
55
  expect { VCR::Cassette.new('0_3_1_cassette') }.to raise_error(/The VCR cassette 0_3_1_cassette.yml uses an old format that is now deprecated/)
56
56
  end
57
57
 
@@ -65,63 +65,56 @@ describe VCR::Cassette do
65
65
  }.to raise_error(ArgumentError)
66
66
  end
67
67
 
68
- it 'creates a stubs checkpoint on the http_stubbing_adapter' do
69
- VCR.http_stubbing_adapter.should_receive(:create_stubs_checkpoint).with('example').once
70
- VCR::Cassette.new('example')
68
+ it 'does not raise an error in the case of an empty file' do
69
+ VCR::Config.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec"
70
+ VCR::Cassette.new('empty', :record => :none).recorded_interactions.should == []
71
71
  end
72
72
 
73
- describe 'ERB support' do
74
- before(:each) do
75
- @orig_default_options = VCR::Config.default_cassette_options
76
- end
73
+ it 'creates a stubs checkpoint on the http_stubbing_adapter' do
74
+ cassette = nil
77
75
 
78
- after(:each) do
79
- VCR::Config.default_cassette_options = @orig_default_options
76
+ VCR.http_stubbing_adapter.should_receive(:create_stubs_checkpoint) do |c|
77
+ cassette = c
80
78
  end
81
79
 
82
- def cassette_body(name, options = {})
83
- VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
84
- VCR::Cassette.new(name, options.merge(:record => :new_episodes)).recorded_interactions.first.response.body
85
- end
80
+ VCR::Cassette.new('example').should equal(cassette)
81
+ end
86
82
 
87
- it "compiles a template as ERB if the :erb option is passed as true" do
88
- cassette_body('erb_with_no_vars', :erb => true).should == 'sum: 3'
83
+ describe "reading the file from disk" do
84
+ before(:each) do
85
+ VCR::Config.cassette_library_dir = "cassette_lib"
86
+ File.stub(:size? => true)
89
87
  end
90
88
 
91
- it "compiles a template as ERB if the default :erb option is true, and no option is passed to the cassette" do
92
- VCR::Config.default_cassette_options = { :erb => true }
93
- cassette_body('erb_with_no_vars').should == 'sum: 3'
94
- end
89
+ it 'reads the appropriate file from disk using a VCR::Cassette::Reader' do
90
+ VCR::Cassette::Reader.should_receive(:new).with(
91
+ 'cassette_lib/foo.yml', anything
92
+ ).and_return(mock('reader', :read => [].to_yaml))
95
93
 
96
- it "does not compile a template as ERB if the default :erb option is true, and :erb => false is passed to the cassette" do
97
- VCR::Config.default_cassette_options = { :erb => true }
98
- cassette_body('erb_with_no_vars', :erb => false).should == 'sum: <%= 1 + 2 %>'
94
+ VCR::Cassette.new('foo', :record => :new_episodes)
99
95
  end
100
96
 
101
- it "compiles a template as ERB if the :erb option is passed a hash" do
102
- cassette_body('erb_with_vars', :erb => { :var1 => 'a', :var3 => 'c', :var2 => 'b' }).should == 'var1: a; var2: b; var3: c'
103
- end
97
+ [true, false, nil, { }].each do |erb|
98
+ it "passes #{erb.inspect} to the VCR::Cassette::Reader when given as the :erb option" do
99
+ # test that it overrides the default
100
+ VCR::Config.default_cassette_options = { :erb => true }
104
101
 
105
- it "does not compile a template as ERB if the :erb option is not used" do
106
- cassette_body('erb_with_no_vars').should == 'sum: <%= 1 + 2 %>'
107
- end
102
+ VCR::Cassette::Reader.should_receive(:new).with(
103
+ anything, erb
104
+ ).and_return(mock('reader', :read => [].to_yaml))
108
105
 
109
- it "raises a helpful error if the ERB template references variables that are not passed in the :erb hash" do
110
- expect {
111
- cassette_body('erb_with_vars', :erb => { :var1 => 'a', :var2 => 'b' })
112
- }.to raise_error(VCR::Cassette::MissingERBVariableError,
113
- %{The ERB in the erb_with_vars.yml cassette file references undefined variable var3. } +
114
- %{Pass it to the cassette using :erb => #{ { :var1 => 'a', :var2 => 'b' }.merge(:var3 => 'some value').inspect }.}
115
- )
116
- end
106
+ VCR::Cassette.new('foo', :record => :new_episodes, :erb => erb)
107
+ end
108
+
109
+ it "passes #{erb.inspect} to the VCR::Cassette::Reader when it is the default :erb option and none is given" do
110
+ VCR::Config.default_cassette_options = { :erb => erb }
117
111
 
118
- it "raises a helpful error if the ERB template references variables and :erb => true is passed" do
119
- expect {
120
- cassette_body('erb_with_vars', :erb => true)
121
- }.to raise_error(VCR::Cassette::MissingERBVariableError,
122
- %{The ERB in the erb_with_vars.yml cassette file references undefined variable var1. } +
123
- %{Pass it to the cassette using :erb => {:var1=>"some value"}.}
124
- )
112
+ VCR::Cassette::Reader.should_receive(:new).with(
113
+ anything, erb
114
+ ).and_return(mock('reader', :read => [].to_yaml))
115
+
116
+ VCR::Cassette.new('foo', :record => :new_episodes)
117
+ end
125
118
  end
126
119
  end
127
120
 
@@ -194,14 +187,14 @@ describe VCR::Cassette do
194
187
 
195
188
  it "#{ ignore_localhost ? 'does not load' : 'loads' } localhost interactions from the cassette file when http_stubbing_adapter.ignore_localhost is set to #{ignore_localhost}" do
196
189
  VCR.http_stubbing_adapter.stub!(:ignore_localhost?).and_return(ignore_localhost)
197
- VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
190
+ VCR::Config.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec"
198
191
  cassette = VCR::Cassette.new('with_localhost_requests', :record => record_mode)
199
192
  cassette.recorded_interactions.map { |i| URI.parse(i.uri).host }.should =~ expected_uri_hosts
200
193
  end
201
194
  end
202
195
 
203
196
  it "loads the recorded interactions from the library yml file" do
204
- VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
197
+ VCR::Config.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec"
205
198
  cassette = VCR::Cassette.new('example', :record => record_mode)
206
199
 
207
200
  cassette.should have(3).recorded_interactions
@@ -222,20 +215,42 @@ describe VCR::Cassette do
222
215
  end
223
216
 
224
217
  if stub_requests
218
+ it 'invokes the appropriately tagged before_playback hooks' do
219
+ VCR::Config.should_receive(:invoke_hook).with(
220
+ :before_playback,
221
+ :foo,
222
+ an_instance_of(VCR::HTTPInteraction),
223
+ an_instance_of(VCR::Cassette)
224
+ ).exactly(3).times
225
+
226
+ cassette = VCR::Cassette.new('example', :record => record_mode, :tag => :foo)
227
+ cassette.should have(3).recorded_interactions
228
+ end
229
+
230
+ it 'does not playback any interactions that are ignored in a before_playback hook' do
231
+ VCR.config do |c|
232
+ c.before_playback { |i| i.ignore! if i.request.uri =~ /foo/ }
233
+ end
234
+
235
+ VCR::Config.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec"
236
+ cassette = VCR::Cassette.new('example', :record => record_mode)
237
+ cassette.should have(2).recorded_interactions
238
+ end
239
+
225
240
  it "stubs the recorded requests with the http stubbing adapter" do
226
- VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
241
+ VCR::Config.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec"
227
242
  VCR.http_stubbing_adapter.should_receive(:stub_requests).with([an_instance_of(VCR::HTTPInteraction)]*3, anything)
228
243
  cassette = VCR::Cassette.new('example', :record => record_mode)
229
244
  end
230
245
 
231
246
  it "passes the :match_request_on option to #stub_requests" do
232
- VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
247
+ VCR::Config.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec"
233
248
  VCR.http_stubbing_adapter.should_receive(:stub_requests).with(anything, [:body, :headers])
234
249
  cassette = VCR::Cassette.new('example', :record => record_mode, :match_requests_on => [:body, :headers])
235
250
  end
236
251
  else
237
252
  it "does not stub the recorded requests with the http stubbing adapter" do
238
- VCR::Config.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
253
+ VCR::Config.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec"
239
254
  VCR.http_stubbing_adapter.should_not_receive(:stub_requests)
240
255
  cassette = VCR::Cassette.new('example', :record => record_mode)
241
256
  end
@@ -245,7 +260,7 @@ describe VCR::Cassette do
245
260
  end
246
261
 
247
262
  describe '#eject' do
248
- temp_dir File.expand_path(File.dirname(__FILE__) + '/fixtures/cassette_spec_eject'), :assign_to_cassette_library_dir => true
263
+ temp_dir "#{VCR::SPEC_ROOT}/fixtures/cassette_spec_eject", :assign_to_cassette_library_dir => true
249
264
 
250
265
  [true, false].each do |orig_http_connections_allowed|
251
266
  it "resets #{orig_http_connections_allowed} on the http stubbing adapter if it was originally #{orig_http_connections_allowed}" do
@@ -271,6 +286,52 @@ describe VCR::Cassette do
271
286
  saved_recorded_interactions.should == recorded_interactions
272
287
  end
273
288
 
289
+ it 'invokes the appropriately tagged before_record hooks' do
290
+ interactions = [
291
+ VCR::HTTPInteraction.new(:req_sig_1, :response_1),
292
+ VCR::HTTPInteraction.new(:req_sig_2, :response_2)
293
+ ]
294
+
295
+ cassette = VCR::Cassette.new('example', :tag => :foo)
296
+ cassette.stub!(:new_recorded_interactions).and_return(interactions)
297
+
298
+ interactions.each do |i|
299
+ VCR::Config.should_receive(:invoke_hook).with(
300
+ :before_record,
301
+ :foo,
302
+ i,
303
+ cassette
304
+ ).ordered
305
+ end
306
+
307
+ cassette.eject
308
+ end
309
+
310
+ it 'does not record interactions that have been ignored' do
311
+ interaction_1 = VCR::HTTPInteraction.new(:request_1, :response_1)
312
+ interaction_2 = VCR::HTTPInteraction.new(:request_2, :response_2)
313
+
314
+ interaction_1.ignore!
315
+
316
+ cassette = VCR::Cassette.new('test_cassette')
317
+ cassette.stub!(:new_recorded_interactions).and_return([interaction_1, interaction_2])
318
+ cassette.eject
319
+
320
+ saved_recorded_interactions = YAML.load_file(cassette.file)
321
+ saved_recorded_interactions.should == [interaction_2]
322
+ end
323
+
324
+ it 'does not write the cassette to disk if all interactions have been ignored' do
325
+ interaction_1 = VCR::HTTPInteraction.new(:request_1, :response_1)
326
+ interaction_1.ignore!
327
+
328
+ cassette = VCR::Cassette.new('test_cassette')
329
+ cassette.stub!(:new_recorded_interactions).and_return([interaction_1])
330
+ cassette.eject
331
+
332
+ File.should_not exist(cassette.file)
333
+ end
334
+
274
335
  it "writes the recorded interactions to a subdirectory if the cassette name includes a directory" do
275
336
  recorded_interactions = [VCR::HTTPInteraction.new(:the_request, :the_response)]
276
337
  cassette = VCR::Cassette.new('subdirectory/test_cassette')
@@ -283,17 +344,17 @@ describe VCR::Cassette do
283
344
 
284
345
  [:all, :none, :new_episodes].each do |record_mode|
285
346
  context "for a :record => :#{record_mode} cassette with previously recorded interactions" do
286
- temp_dir File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec/temp"), :assign_to_cassette_library_dir => true
347
+ temp_dir "#{VCR::SPEC_ROOT}/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec/temp", :assign_to_cassette_library_dir => true
287
348
 
288
349
  subject { VCR::Cassette.new('example', :record => record_mode, :match_requests_on => [:uri]) }
289
350
 
290
351
  before(:each) do
291
- base_dir = File.expand_path(File.dirname(__FILE__) + "/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec")
352
+ base_dir = "#{VCR::SPEC_ROOT}/fixtures/#{YAML_SERIALIZATION_VERSION}/cassette_spec"
292
353
  FileUtils.cp(base_dir + "/example.yml", base_dir + "/temp/example.yml")
293
354
  end
294
355
 
295
356
  it "restore the stubs checkpoint on the http stubbing adapter" do
296
- VCR.http_stubbing_adapter.should_receive(:restore_stubs_checkpoint).with('example')
357
+ VCR.http_stubbing_adapter.should_receive(:restore_stubs_checkpoint).with(subject)
297
358
  subject.eject
298
359
  end
299
360