vcr 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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